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