Home | History | Annotate | Download | only in ast
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/ast/ast-numbering.h"
      6 
      7 #include "src/ast/ast.h"
      8 #include "src/ast/scopes.h"
      9 #include "src/compiler.h"
     10 #include "src/objects-inl.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
     16  public:
     17   AstNumberingVisitor(uintptr_t stack_limit, Zone* zone,
     18                       Compiler::EagerInnerFunctionLiterals* eager_literals)
     19       : zone_(zone),
     20         eager_literals_(eager_literals),
     21         next_id_(BailoutId::FirstUsable().ToInt()),
     22         yield_count_(0),
     23         properties_(zone),
     24         language_mode_(SLOPPY),
     25         slot_cache_(zone),
     26         disable_crankshaft_reason_(kNoReason),
     27         dont_optimize_reason_(kNoReason),
     28         catch_prediction_(HandlerTable::UNCAUGHT) {
     29     InitializeAstVisitor(stack_limit);
     30   }
     31 
     32   bool Renumber(FunctionLiteral* node);
     33 
     34  private:
     35 // AST node visitor interface.
     36 #define DEFINE_VISIT(type) void Visit##type(type* node);
     37   AST_NODE_LIST(DEFINE_VISIT)
     38 #undef DEFINE_VISIT
     39 
     40   void VisitVariableProxy(VariableProxy* node, TypeofMode typeof_mode);
     41   void VisitVariableProxyReference(VariableProxy* node);
     42   void VisitPropertyReference(Property* node);
     43   void VisitReference(Expression* expr);
     44 
     45   void VisitStatementsAndDeclarations(Block* node);
     46   void VisitStatements(ZoneList<Statement*>* statements);
     47   void VisitDeclarations(Declaration::List* declarations);
     48   void VisitArguments(ZoneList<Expression*>* arguments);
     49   void VisitLiteralProperty(LiteralProperty* property);
     50 
     51   int ReserveIdRange(int n) {
     52     int tmp = next_id_;
     53     next_id_ += n;
     54     return tmp;
     55   }
     56 
     57   void IncrementNodeCount() { properties_.add_node_count(1); }
     58   void DisableSelfOptimization() {
     59     properties_.flags() |= AstProperties::kDontSelfOptimize;
     60   }
     61   void DisableOptimization(BailoutReason reason) {
     62     dont_optimize_reason_ = reason;
     63     DisableSelfOptimization();
     64   }
     65   void DisableFullCodegenAndCrankshaft(BailoutReason reason) {
     66     disable_crankshaft_reason_ = reason;
     67     properties_.flags() |= AstProperties::kMustUseIgnitionTurbo;
     68   }
     69 
     70   template <typename Node>
     71   void ReserveFeedbackSlots(Node* node) {
     72     node->AssignFeedbackSlots(properties_.get_spec(), language_mode_,
     73                               &slot_cache_);
     74   }
     75 
     76   class LanguageModeScope {
     77    public:
     78     LanguageModeScope(AstNumberingVisitor* visitor, LanguageMode language_mode)
     79         : visitor_(visitor), outer_language_mode_(visitor->language_mode_) {
     80       visitor_->language_mode_ = language_mode;
     81     }
     82     ~LanguageModeScope() { visitor_->language_mode_ = outer_language_mode_; }
     83 
     84    private:
     85     AstNumberingVisitor* visitor_;
     86     LanguageMode outer_language_mode_;
     87   };
     88 
     89   BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
     90 
     91   Zone* zone() const { return zone_; }
     92 
     93   Zone* zone_;
     94   Compiler::EagerInnerFunctionLiterals* eager_literals_;
     95   int next_id_;
     96   int yield_count_;
     97   AstProperties properties_;
     98   LanguageMode language_mode_;
     99   // The slot cache allows us to reuse certain feedback slots.
    100   FeedbackSlotCache slot_cache_;
    101   BailoutReason disable_crankshaft_reason_;
    102   BailoutReason dont_optimize_reason_;
    103   HandlerTable::CatchPrediction catch_prediction_;
    104 
    105   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
    106   DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
    107 };
    108 
    109 
    110 void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
    111   IncrementNodeCount();
    112   VisitVariableProxy(node->proxy());
    113 }
    114 
    115 
    116 void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {
    117   IncrementNodeCount();
    118 }
    119 
    120 
    121 void AstNumberingVisitor::VisitSloppyBlockFunctionStatement(
    122     SloppyBlockFunctionStatement* node) {
    123   IncrementNodeCount();
    124   Visit(node->statement());
    125 }
    126 
    127 
    128 void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {
    129   IncrementNodeCount();
    130 }
    131 
    132 
    133 void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {
    134   IncrementNodeCount();
    135 }
    136 
    137 
    138 void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
    139   IncrementNodeCount();
    140   DisableFullCodegenAndCrankshaft(kDebuggerStatement);
    141 }
    142 
    143 
    144 void AstNumberingVisitor::VisitNativeFunctionLiteral(
    145     NativeFunctionLiteral* node) {
    146   IncrementNodeCount();
    147   DisableOptimization(kNativeFunctionLiteral);
    148   node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids()));
    149   ReserveFeedbackSlots(node);
    150 }
    151 
    152 
    153 void AstNumberingVisitor::VisitDoExpression(DoExpression* node) {
    154   IncrementNodeCount();
    155   node->set_base_id(ReserveIdRange(DoExpression::num_ids()));
    156   Visit(node->block());
    157   Visit(node->result());
    158 }
    159 
    160 
    161 void AstNumberingVisitor::VisitLiteral(Literal* node) {
    162   IncrementNodeCount();
    163   node->set_base_id(ReserveIdRange(Literal::num_ids()));
    164 }
    165 
    166 
    167 void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
    168   IncrementNodeCount();
    169   node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
    170   ReserveFeedbackSlots(node);
    171 }
    172 
    173 
    174 void AstNumberingVisitor::VisitVariableProxyReference(VariableProxy* node) {
    175   IncrementNodeCount();
    176   switch (node->var()->location()) {
    177     case VariableLocation::LOOKUP:
    178       DisableFullCodegenAndCrankshaft(
    179           kReferenceToAVariableWhichRequiresDynamicLookup);
    180       break;
    181     case VariableLocation::MODULE:
    182       DisableFullCodegenAndCrankshaft(kReferenceToModuleVariable);
    183       break;
    184     default:
    185       break;
    186   }
    187   node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
    188 }
    189 
    190 void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node,
    191                                              TypeofMode typeof_mode) {
    192   VisitVariableProxyReference(node);
    193   node->AssignFeedbackSlots(properties_.get_spec(), typeof_mode, &slot_cache_);
    194 }
    195 
    196 void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
    197   VisitVariableProxy(node, NOT_INSIDE_TYPEOF);
    198 }
    199 
    200 
    201 void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
    202   IncrementNodeCount();
    203   node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
    204 }
    205 
    206 
    207 void AstNumberingVisitor::VisitSuperPropertyReference(
    208     SuperPropertyReference* node) {
    209   IncrementNodeCount();
    210   DisableFullCodegenAndCrankshaft(kSuperReference);
    211   node->set_base_id(ReserveIdRange(SuperPropertyReference::num_ids()));
    212   Visit(node->this_var());
    213   Visit(node->home_object());
    214 }
    215 
    216 
    217 void AstNumberingVisitor::VisitSuperCallReference(SuperCallReference* node) {
    218   IncrementNodeCount();
    219   DisableFullCodegenAndCrankshaft(kSuperReference);
    220   node->set_base_id(ReserveIdRange(SuperCallReference::num_ids()));
    221   Visit(node->this_var());
    222   Visit(node->new_target_var());
    223   Visit(node->this_function_var());
    224 }
    225 
    226 
    227 void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
    228   IncrementNodeCount();
    229   Visit(node->expression());
    230 }
    231 
    232 
    233 void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
    234   IncrementNodeCount();
    235   Visit(node->expression());
    236 
    237   DCHECK(!node->is_async_return() ||
    238          properties_.flags() & AstProperties::kMustUseIgnitionTurbo);
    239 }
    240 
    241 
    242 void AstNumberingVisitor::VisitYield(Yield* node) {
    243   node->set_yield_id(yield_count_);
    244   yield_count_++;
    245   IncrementNodeCount();
    246   node->set_base_id(ReserveIdRange(Yield::num_ids()));
    247   Visit(node->generator_object());
    248   Visit(node->expression());
    249 }
    250 
    251 
    252 void AstNumberingVisitor::VisitThrow(Throw* node) {
    253   IncrementNodeCount();
    254   node->set_base_id(ReserveIdRange(Throw::num_ids()));
    255   Visit(node->exception());
    256 }
    257 
    258 
    259 void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
    260   IncrementNodeCount();
    261   node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
    262   if ((node->op() == Token::TYPEOF) && node->expression()->IsVariableProxy()) {
    263     VariableProxy* proxy = node->expression()->AsVariableProxy();
    264     VisitVariableProxy(proxy, INSIDE_TYPEOF);
    265   } else {
    266     Visit(node->expression());
    267   }
    268 }
    269 
    270 
    271 void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
    272   IncrementNodeCount();
    273   node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
    274   Visit(node->expression());
    275   ReserveFeedbackSlots(node);
    276 }
    277 
    278 
    279 void AstNumberingVisitor::VisitBlock(Block* node) {
    280   IncrementNodeCount();
    281   node->set_base_id(ReserveIdRange(Block::num_ids()));
    282   Scope* scope = node->scope();
    283   if (scope != nullptr) {
    284     LanguageModeScope language_mode_scope(this, scope->language_mode());
    285     VisitStatementsAndDeclarations(node);
    286   } else {
    287     VisitStatementsAndDeclarations(node);
    288   }
    289 }
    290 
    291 void AstNumberingVisitor::VisitStatementsAndDeclarations(Block* node) {
    292   Scope* scope = node->scope();
    293   DCHECK(scope == nullptr || !scope->HasBeenRemoved());
    294   if (scope) VisitDeclarations(scope->declarations());
    295   VisitStatements(node->statements());
    296 }
    297 
    298 void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
    299   IncrementNodeCount();
    300   VisitVariableProxy(node->proxy());
    301   VisitFunctionLiteral(node->fun());
    302 }
    303 
    304 
    305 void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
    306   IncrementNodeCount();
    307   node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
    308   VisitArguments(node->arguments());
    309   // To support catch prediction within async/await:
    310   //
    311   // The AstNumberingVisitor is when catch prediction currently occurs, and it
    312   // is the only common point that has access to this information. The parser
    313   // just doesn't know yet. Take the following two cases of catch prediction:
    314   //
    315   // try { await fn(); } catch (e) { }
    316   // try { await fn(); } finally { }
    317   //
    318   // When parsing the await that we want to mark as caught or uncaught, it's
    319   // not yet known whether it will be followed by a 'finally' or a 'catch.
    320   // The AstNumberingVisitor is what learns whether it is caught. To make
    321   // the information available later to the runtime, the AstNumberingVisitor
    322   // has to stash it somewhere. Changing the runtime function into another
    323   // one in ast-numbering seemed like a simple and straightforward solution to
    324   // that problem.
    325   if (node->is_jsruntime() &&
    326       node->context_index() == Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX &&
    327       catch_prediction_ == HandlerTable::ASYNC_AWAIT) {
    328     node->set_context_index(Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX);
    329   }
    330 }
    331 
    332 
    333 void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
    334   IncrementNodeCount();
    335   DisableFullCodegenAndCrankshaft(kWithStatement);
    336   Visit(node->expression());
    337   Visit(node->statement());
    338 }
    339 
    340 
    341 void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
    342   IncrementNodeCount();
    343   DisableSelfOptimization();
    344   node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
    345   node->set_first_yield_id(yield_count_);
    346   Visit(node->body());
    347   Visit(node->cond());
    348   node->set_yield_count(yield_count_ - node->first_yield_id());
    349 }
    350 
    351 
    352 void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
    353   IncrementNodeCount();
    354   DisableSelfOptimization();
    355   node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
    356   node->set_first_yield_id(yield_count_);
    357   Visit(node->cond());
    358   Visit(node->body());
    359   node->set_yield_count(yield_count_ - node->first_yield_id());
    360 }
    361 
    362 
    363 void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
    364   DCHECK(node->scope() == nullptr || !node->scope()->HasBeenRemoved());
    365   IncrementNodeCount();
    366   DisableFullCodegenAndCrankshaft(kTryCatchStatement);
    367   {
    368     const HandlerTable::CatchPrediction old_prediction = catch_prediction_;
    369     // This node uses its own prediction, unless it's "uncaught", in which case
    370     // we adopt the prediction of the outer try-block.
    371     HandlerTable::CatchPrediction catch_prediction = node->catch_prediction();
    372     if (catch_prediction != HandlerTable::UNCAUGHT) {
    373       catch_prediction_ = catch_prediction;
    374     }
    375     node->set_catch_prediction(catch_prediction_);
    376     Visit(node->try_block());
    377     catch_prediction_ = old_prediction;
    378   }
    379   Visit(node->catch_block());
    380 }
    381 
    382 
    383 void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
    384   IncrementNodeCount();
    385   DisableFullCodegenAndCrankshaft(kTryFinallyStatement);
    386   // We can't know whether the finally block will override ("catch") an
    387   // exception thrown in the try block, so we just adopt the outer prediction.
    388   node->set_catch_prediction(catch_prediction_);
    389   Visit(node->try_block());
    390   Visit(node->finally_block());
    391 }
    392 
    393 
    394 void AstNumberingVisitor::VisitPropertyReference(Property* node) {
    395   IncrementNodeCount();
    396   node->set_base_id(ReserveIdRange(Property::num_ids()));
    397   Visit(node->key());
    398   Visit(node->obj());
    399 }
    400 
    401 
    402 void AstNumberingVisitor::VisitReference(Expression* expr) {
    403   DCHECK(expr->IsProperty() || expr->IsVariableProxy());
    404   if (expr->IsProperty()) {
    405     VisitPropertyReference(expr->AsProperty());
    406   } else {
    407     VisitVariableProxyReference(expr->AsVariableProxy());
    408   }
    409 }
    410 
    411 
    412 void AstNumberingVisitor::VisitProperty(Property* node) {
    413   VisitPropertyReference(node);
    414   ReserveFeedbackSlots(node);
    415 }
    416 
    417 
    418 void AstNumberingVisitor::VisitAssignment(Assignment* node) {
    419   IncrementNodeCount();
    420   node->set_base_id(ReserveIdRange(Assignment::num_ids()));
    421 
    422   if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
    423   VisitReference(node->target());
    424   Visit(node->value());
    425   ReserveFeedbackSlots(node);
    426 }
    427 
    428 
    429 void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
    430   IncrementNodeCount();
    431   node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
    432   Visit(node->left());
    433   Visit(node->right());
    434   ReserveFeedbackSlots(node);
    435 }
    436 
    437 
    438 void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
    439   IncrementNodeCount();
    440   node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
    441   Visit(node->left());
    442   Visit(node->right());
    443   ReserveFeedbackSlots(node);
    444 }
    445 
    446 void AstNumberingVisitor::VisitSpread(Spread* node) {
    447   IncrementNodeCount();
    448   // We can only get here from spread calls currently.
    449   DisableFullCodegenAndCrankshaft(kSpreadCall);
    450   node->set_base_id(ReserveIdRange(Spread::num_ids()));
    451   Visit(node->expression());
    452 }
    453 
    454 void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) {
    455   UNREACHABLE();
    456 }
    457 
    458 void AstNumberingVisitor::VisitGetIterator(GetIterator* node) {
    459   IncrementNodeCount();
    460   DisableFullCodegenAndCrankshaft(kGetIterator);
    461   node->set_base_id(ReserveIdRange(GetIterator::num_ids()));
    462   Visit(node->iterable());
    463   ReserveFeedbackSlots(node);
    464 }
    465 
    466 void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
    467   IncrementNodeCount();
    468   DisableSelfOptimization();
    469   node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
    470   Visit(node->enumerable());  // Not part of loop.
    471   node->set_first_yield_id(yield_count_);
    472   Visit(node->each());
    473   Visit(node->body());
    474   node->set_yield_count(yield_count_ - node->first_yield_id());
    475   ReserveFeedbackSlots(node);
    476 }
    477 
    478 
    479 void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
    480   IncrementNodeCount();
    481   DisableFullCodegenAndCrankshaft(kForOfStatement);
    482   node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
    483   Visit(node->assign_iterator());  // Not part of loop.
    484   node->set_first_yield_id(yield_count_);
    485   Visit(node->next_result());
    486   Visit(node->result_done());
    487   Visit(node->assign_each());
    488   Visit(node->body());
    489   node->set_yield_count(yield_count_ - node->first_yield_id());
    490 }
    491 
    492 
    493 void AstNumberingVisitor::VisitConditional(Conditional* node) {
    494   IncrementNodeCount();
    495   node->set_base_id(ReserveIdRange(Conditional::num_ids()));
    496   Visit(node->condition());
    497   Visit(node->then_expression());
    498   Visit(node->else_expression());
    499 }
    500 
    501 
    502 void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
    503   IncrementNodeCount();
    504   node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
    505   Visit(node->condition());
    506   Visit(node->then_statement());
    507   if (node->HasElseStatement()) {
    508     Visit(node->else_statement());
    509   }
    510 }
    511 
    512 
    513 void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
    514   IncrementNodeCount();
    515   node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
    516   Visit(node->tag());
    517   ZoneList<CaseClause*>* cases = node->cases();
    518   for (int i = 0; i < cases->length(); i++) {
    519     VisitCaseClause(cases->at(i));
    520   }
    521 }
    522 
    523 
    524 void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
    525   IncrementNodeCount();
    526   node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
    527   if (!node->is_default()) Visit(node->label());
    528   VisitStatements(node->statements());
    529   ReserveFeedbackSlots(node);
    530 }
    531 
    532 
    533 void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
    534   IncrementNodeCount();
    535   DisableSelfOptimization();
    536   node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
    537   if (node->init() != NULL) Visit(node->init());  // Not part of loop.
    538   node->set_first_yield_id(yield_count_);
    539   if (node->cond() != NULL) Visit(node->cond());
    540   if (node->next() != NULL) Visit(node->next());
    541   Visit(node->body());
    542   node->set_yield_count(yield_count_ - node->first_yield_id());
    543 }
    544 
    545 
    546 void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
    547   IncrementNodeCount();
    548   DisableFullCodegenAndCrankshaft(kClassLiteral);
    549   node->set_base_id(ReserveIdRange(ClassLiteral::num_ids()));
    550   if (node->extends()) Visit(node->extends());
    551   if (node->constructor()) Visit(node->constructor());
    552   if (node->class_variable_proxy()) {
    553     VisitVariableProxy(node->class_variable_proxy());
    554   }
    555   for (int i = 0; i < node->properties()->length(); i++) {
    556     VisitLiteralProperty(node->properties()->at(i));
    557   }
    558   ReserveFeedbackSlots(node);
    559 }
    560 
    561 
    562 void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
    563   IncrementNodeCount();
    564   node->set_base_id(ReserveIdRange(node->num_ids()));
    565   for (int i = 0; i < node->properties()->length(); i++) {
    566     VisitLiteralProperty(node->properties()->at(i));
    567   }
    568   node->InitDepthAndFlags();
    569   // Mark all computed expressions that are bound to a key that
    570   // is shadowed by a later occurrence of the same key. For the
    571   // marked expressions, no store code will be is emitted.
    572   node->CalculateEmitStore(zone_);
    573   ReserveFeedbackSlots(node);
    574 }
    575 
    576 void AstNumberingVisitor::VisitLiteralProperty(LiteralProperty* node) {
    577   if (node->is_computed_name())
    578     DisableFullCodegenAndCrankshaft(kComputedPropertyName);
    579   Visit(node->key());
    580   Visit(node->value());
    581 }
    582 
    583 void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
    584   IncrementNodeCount();
    585   node->set_base_id(ReserveIdRange(node->num_ids()));
    586   for (int i = 0; i < node->values()->length(); i++) {
    587     Visit(node->values()->at(i));
    588   }
    589   node->InitDepthAndFlags();
    590   ReserveFeedbackSlots(node);
    591 }
    592 
    593 
    594 void AstNumberingVisitor::VisitCall(Call* node) {
    595   if (node->is_possibly_eval()) {
    596     DisableFullCodegenAndCrankshaft(kFunctionCallsEval);
    597   }
    598   IncrementNodeCount();
    599   ReserveFeedbackSlots(node);
    600   node->set_base_id(ReserveIdRange(Call::num_ids()));
    601   Visit(node->expression());
    602   VisitArguments(node->arguments());
    603 }
    604 
    605 
    606 void AstNumberingVisitor::VisitCallNew(CallNew* node) {
    607   IncrementNodeCount();
    608   ReserveFeedbackSlots(node);
    609   node->set_base_id(ReserveIdRange(CallNew::num_ids()));
    610   Visit(node->expression());
    611   VisitArguments(node->arguments());
    612 }
    613 
    614 
    615 void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
    616   if (statements == NULL) return;
    617   for (int i = 0; i < statements->length(); i++) {
    618     Visit(statements->at(i));
    619   }
    620 }
    621 
    622 void AstNumberingVisitor::VisitDeclarations(Declaration::List* decls) {
    623   for (Declaration* decl : *decls) Visit(decl);
    624 }
    625 
    626 
    627 void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
    628   for (int i = 0; i < arguments->length(); i++) {
    629     Visit(arguments->at(i));
    630   }
    631 }
    632 
    633 
    634 void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
    635   IncrementNodeCount();
    636   node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
    637   if (node->ShouldEagerCompile()) {
    638     if (eager_literals_) {
    639       eager_literals_->Add(new (zone())
    640                                ThreadedListZoneEntry<FunctionLiteral*>(node));
    641     }
    642 
    643     // If the function literal is being eagerly compiled, recurse into the
    644     // declarations and body of the function literal.
    645     if (!AstNumbering::Renumber(stack_limit_, zone_, node, eager_literals_)) {
    646       SetStackOverflow();
    647       return;
    648     }
    649   }
    650   ReserveFeedbackSlots(node);
    651 }
    652 
    653 
    654 void AstNumberingVisitor::VisitRewritableExpression(
    655     RewritableExpression* node) {
    656   IncrementNodeCount();
    657   node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
    658   Visit(node->expression());
    659 }
    660 
    661 
    662 bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
    663   DeclarationScope* scope = node->scope();
    664   DCHECK(!scope->HasBeenRemoved());
    665 
    666   if (scope->new_target_var() != nullptr ||
    667       scope->this_function_var() != nullptr) {
    668     DisableFullCodegenAndCrankshaft(kSuperReference);
    669   }
    670 
    671   if (scope->arguments() != nullptr &&
    672       !scope->arguments()->IsStackAllocated()) {
    673     DisableFullCodegenAndCrankshaft(kContextAllocatedArguments);
    674   }
    675 
    676   if (scope->rest_parameter() != nullptr) {
    677     DisableFullCodegenAndCrankshaft(kRestParameter);
    678   }
    679 
    680   if (IsResumableFunction(node->kind())) {
    681     DisableFullCodegenAndCrankshaft(kGenerator);
    682   }
    683 
    684   if (IsClassConstructor(node->kind())) {
    685     DisableFullCodegenAndCrankshaft(kClassConstructorFunction);
    686   }
    687 
    688   LanguageModeScope language_mode_scope(this, node->language_mode());
    689 
    690   VisitDeclarations(scope->declarations());
    691   VisitStatements(node->body());
    692 
    693   node->set_ast_properties(&properties_);
    694   node->set_dont_optimize_reason(dont_optimize_reason());
    695   node->set_yield_count(yield_count_);
    696 
    697   if (FLAG_trace_opt) {
    698     if (disable_crankshaft_reason_ != kNoReason) {
    699       // TODO(leszeks): This is a quick'n'dirty fix to allow the debug name of
    700       // the function to be accessed in the below print. This DCHECK will fail
    701       // if we move ast numbering off the main thread, but that won't be before
    702       // we remove FCG, in which case this entire check isn't necessary anyway.
    703       AllowHandleDereference allow_deref;
    704       DCHECK(!node->debug_name().is_null());
    705 
    706       PrintF("[enforcing Ignition and TurboFan for %s because: %s\n",
    707              node->debug_name()->ToCString().get(),
    708              GetBailoutReason(disable_crankshaft_reason_));
    709     }
    710   }
    711 
    712   return !HasStackOverflow();
    713 }
    714 
    715 bool AstNumbering::Renumber(
    716     uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
    717     Compiler::EagerInnerFunctionLiterals* eager_literals) {
    718   DisallowHeapAllocation no_allocation;
    719   DisallowHandleAllocation no_handles;
    720   DisallowHandleDereference no_deref;
    721 
    722   AstNumberingVisitor visitor(stack_limit, zone, eager_literals);
    723   return visitor.Renumber(function);
    724 }
    725 }  // namespace internal
    726 }  // namespace v8
    727