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