• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
AstNumberingVisitor(uintptr_t stack_limit,Zone * zone,Compiler::EagerInnerFunctionLiterals * eager_literals)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 
ReserveIdRange(int n)51   int ReserveIdRange(int n) {
52     int tmp = next_id_;
53     next_id_ += n;
54     return tmp;
55   }
56 
IncrementNodeCount()57   void IncrementNodeCount() { properties_.add_node_count(1); }
DisableSelfOptimization()58   void DisableSelfOptimization() {
59     properties_.flags() |= AstProperties::kDontSelfOptimize;
60   }
DisableOptimization(BailoutReason reason)61   void DisableOptimization(BailoutReason reason) {
62     dont_optimize_reason_ = reason;
63     DisableSelfOptimization();
64   }
DisableFullCodegenAndCrankshaft(BailoutReason reason)65   void DisableFullCodegenAndCrankshaft(BailoutReason reason) {
66     disable_crankshaft_reason_ = reason;
67     properties_.flags() |= AstProperties::kMustUseIgnitionTurbo;
68   }
69 
70   template <typename Node>
ReserveFeedbackSlots(Node * node)71   void ReserveFeedbackSlots(Node* node) {
72     node->AssignFeedbackSlots(properties_.get_spec(), language_mode_,
73                               &slot_cache_);
74   }
75 
76   class LanguageModeScope {
77    public:
LanguageModeScope(AstNumberingVisitor * visitor,LanguageMode language_mode)78     LanguageModeScope(AstNumberingVisitor* visitor, LanguageMode language_mode)
79         : visitor_(visitor), outer_language_mode_(visitor->language_mode_) {
80       visitor_->language_mode_ = language_mode;
81     }
~LanguageModeScope()82     ~LanguageModeScope() { visitor_->language_mode_ = outer_language_mode_; }
83 
84    private:
85     AstNumberingVisitor* visitor_;
86     LanguageMode outer_language_mode_;
87   };
88 
dont_optimize_reason() const89   BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
90 
zone() const91   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 
VisitVariableDeclaration(VariableDeclaration * node)110 void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
111   IncrementNodeCount();
112   VisitVariableProxy(node->proxy());
113 }
114 
115 
VisitEmptyStatement(EmptyStatement * node)116 void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {
117   IncrementNodeCount();
118 }
119 
120 
VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement * node)121 void AstNumberingVisitor::VisitSloppyBlockFunctionStatement(
122     SloppyBlockFunctionStatement* node) {
123   IncrementNodeCount();
124   Visit(node->statement());
125 }
126 
127 
VisitContinueStatement(ContinueStatement * node)128 void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {
129   IncrementNodeCount();
130 }
131 
132 
VisitBreakStatement(BreakStatement * node)133 void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {
134   IncrementNodeCount();
135 }
136 
137 
VisitDebuggerStatement(DebuggerStatement * node)138 void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
139   IncrementNodeCount();
140   DisableFullCodegenAndCrankshaft(kDebuggerStatement);
141 }
142 
143 
VisitNativeFunctionLiteral(NativeFunctionLiteral * node)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 
VisitDoExpression(DoExpression * node)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 
VisitLiteral(Literal * node)161 void AstNumberingVisitor::VisitLiteral(Literal* node) {
162   IncrementNodeCount();
163   node->set_base_id(ReserveIdRange(Literal::num_ids()));
164 }
165 
166 
VisitRegExpLiteral(RegExpLiteral * node)167 void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
168   IncrementNodeCount();
169   node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
170   ReserveFeedbackSlots(node);
171 }
172 
173 
VisitVariableProxyReference(VariableProxy * node)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 
VisitVariableProxy(VariableProxy * node,TypeofMode typeof_mode)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 
VisitVariableProxy(VariableProxy * node)196 void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
197   VisitVariableProxy(node, NOT_INSIDE_TYPEOF);
198 }
199 
200 
VisitThisFunction(ThisFunction * node)201 void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
202   IncrementNodeCount();
203   node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
204 }
205 
206 
VisitSuperPropertyReference(SuperPropertyReference * node)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 
VisitSuperCallReference(SuperCallReference * node)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 
VisitExpressionStatement(ExpressionStatement * node)227 void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
228   IncrementNodeCount();
229   Visit(node->expression());
230 }
231 
232 
VisitReturnStatement(ReturnStatement * node)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 
VisitYield(Yield * node)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 
VisitThrow(Throw * node)252 void AstNumberingVisitor::VisitThrow(Throw* node) {
253   IncrementNodeCount();
254   node->set_base_id(ReserveIdRange(Throw::num_ids()));
255   Visit(node->exception());
256 }
257 
258 
VisitUnaryOperation(UnaryOperation * node)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 
VisitCountOperation(CountOperation * node)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 
VisitBlock(Block * node)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 
VisitStatementsAndDeclarations(Block * node)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 
VisitFunctionDeclaration(FunctionDeclaration * node)298 void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
299   IncrementNodeCount();
300   VisitVariableProxy(node->proxy());
301   VisitFunctionLiteral(node->fun());
302 }
303 
304 
VisitCallRuntime(CallRuntime * node)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 
VisitWithStatement(WithStatement * node)333 void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
334   IncrementNodeCount();
335   DisableFullCodegenAndCrankshaft(kWithStatement);
336   Visit(node->expression());
337   Visit(node->statement());
338 }
339 
340 
VisitDoWhileStatement(DoWhileStatement * node)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 
VisitWhileStatement(WhileStatement * node)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 
VisitTryCatchStatement(TryCatchStatement * node)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 
VisitTryFinallyStatement(TryFinallyStatement * node)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 
VisitPropertyReference(Property * node)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 
VisitReference(Expression * expr)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 
VisitProperty(Property * node)412 void AstNumberingVisitor::VisitProperty(Property* node) {
413   VisitPropertyReference(node);
414   ReserveFeedbackSlots(node);
415 }
416 
417 
VisitAssignment(Assignment * node)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 
VisitBinaryOperation(BinaryOperation * node)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 
VisitCompareOperation(CompareOperation * node)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 
VisitSpread(Spread * node)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 
VisitEmptyParentheses(EmptyParentheses * node)454 void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) {
455   UNREACHABLE();
456 }
457 
VisitGetIterator(GetIterator * node)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 
VisitForInStatement(ForInStatement * node)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 
VisitForOfStatement(ForOfStatement * node)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 
VisitConditional(Conditional * node)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 
VisitIfStatement(IfStatement * node)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 
VisitSwitchStatement(SwitchStatement * node)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 
VisitCaseClause(CaseClause * node)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 
VisitForStatement(ForStatement * node)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 
VisitClassLiteral(ClassLiteral * node)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 
VisitObjectLiteral(ObjectLiteral * node)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 
VisitLiteralProperty(LiteralProperty * node)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 
VisitArrayLiteral(ArrayLiteral * node)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 
VisitCall(Call * node)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 
VisitCallNew(CallNew * node)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 
VisitStatements(ZoneList<Statement * > * statements)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     if (statements->at(i)->IsJump())
620         break;
621   }
622 }
623 
VisitDeclarations(Declaration::List * decls)624 void AstNumberingVisitor::VisitDeclarations(Declaration::List* decls) {
625   for (Declaration* decl : *decls) Visit(decl);
626 }
627 
628 
VisitArguments(ZoneList<Expression * > * arguments)629 void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
630   for (int i = 0; i < arguments->length(); i++) {
631     Visit(arguments->at(i));
632   }
633 }
634 
635 
VisitFunctionLiteral(FunctionLiteral * node)636 void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
637   IncrementNodeCount();
638   node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
639   if (node->ShouldEagerCompile()) {
640     if (eager_literals_) {
641       eager_literals_->Add(new (zone())
642                                ThreadedListZoneEntry<FunctionLiteral*>(node));
643     }
644 
645     // If the function literal is being eagerly compiled, recurse into the
646     // declarations and body of the function literal.
647     if (!AstNumbering::Renumber(stack_limit_, zone_, node, eager_literals_)) {
648       SetStackOverflow();
649       return;
650     }
651   }
652   ReserveFeedbackSlots(node);
653 }
654 
655 
VisitRewritableExpression(RewritableExpression * node)656 void AstNumberingVisitor::VisitRewritableExpression(
657     RewritableExpression* node) {
658   IncrementNodeCount();
659   node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
660   Visit(node->expression());
661 }
662 
663 
Renumber(FunctionLiteral * node)664 bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
665   DeclarationScope* scope = node->scope();
666   DCHECK(!scope->HasBeenRemoved());
667 
668   if (scope->new_target_var() != nullptr ||
669       scope->this_function_var() != nullptr) {
670     DisableFullCodegenAndCrankshaft(kSuperReference);
671   }
672 
673   if (scope->arguments() != nullptr &&
674       !scope->arguments()->IsStackAllocated()) {
675     DisableFullCodegenAndCrankshaft(kContextAllocatedArguments);
676   }
677 
678   if (scope->rest_parameter() != nullptr) {
679     DisableFullCodegenAndCrankshaft(kRestParameter);
680   }
681 
682   if (IsResumableFunction(node->kind())) {
683     DisableFullCodegenAndCrankshaft(kGenerator);
684   }
685 
686   if (IsClassConstructor(node->kind())) {
687     DisableFullCodegenAndCrankshaft(kClassConstructorFunction);
688   }
689 
690   LanguageModeScope language_mode_scope(this, node->language_mode());
691 
692   VisitDeclarations(scope->declarations());
693   VisitStatements(node->body());
694 
695   node->set_ast_properties(&properties_);
696   node->set_dont_optimize_reason(dont_optimize_reason());
697   node->set_yield_count(yield_count_);
698 
699   if (FLAG_trace_opt) {
700     if (disable_crankshaft_reason_ != kNoReason) {
701       // TODO(leszeks): This is a quick'n'dirty fix to allow the debug name of
702       // the function to be accessed in the below print. This DCHECK will fail
703       // if we move ast numbering off the main thread, but that won't be before
704       // we remove FCG, in which case this entire check isn't necessary anyway.
705       AllowHandleDereference allow_deref;
706       DCHECK(!node->debug_name().is_null());
707 
708       PrintF("[enforcing Ignition and TurboFan for %s because: %s\n",
709              node->debug_name()->ToCString().get(),
710              GetBailoutReason(disable_crankshaft_reason_));
711     }
712   }
713 
714   return !HasStackOverflow();
715 }
716 
Renumber(uintptr_t stack_limit,Zone * zone,FunctionLiteral * function,Compiler::EagerInnerFunctionLiterals * eager_literals)717 bool AstNumbering::Renumber(
718     uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
719     Compiler::EagerInnerFunctionLiterals* eager_literals) {
720   DisallowHeapAllocation no_allocation;
721   DisallowHandleAllocation no_handles;
722   DisallowHandleDereference no_deref;
723 
724   AstNumberingVisitor visitor(stack_limit, zone, eager_literals);
725   return visitor.Renumber(function);
726 }
727 }  // namespace internal
728 }  // namespace v8
729