LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-generator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1587 1628 97.5 %
Date: 2017-04-26 Functions: 117 151 77.5 %

          Line data    Source code
       1             : // Copyright 2015 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/interpreter/bytecode-generator.h"
       6             : 
       7             : #include "src/ast/compile-time-value.h"
       8             : #include "src/ast/scopes.h"
       9             : #include "src/builtins/builtins-constructor.h"
      10             : #include "src/code-stubs.h"
      11             : #include "src/compilation-info.h"
      12             : #include "src/compiler.h"
      13             : #include "src/interpreter/bytecode-flags.h"
      14             : #include "src/interpreter/bytecode-label.h"
      15             : #include "src/interpreter/bytecode-register-allocator.h"
      16             : #include "src/interpreter/control-flow-builders.h"
      17             : #include "src/objects-inl.h"
      18             : #include "src/parsing/parse-info.h"
      19             : #include "src/parsing/token.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : namespace interpreter {
      24             : 
      25             : // Scoped class tracking context objects created by the visitor. Represents
      26             : // mutations of the context chain within the function body, allowing pushing and
      27             : // popping of the current {context_register} during visitation.
      28             : class BytecodeGenerator::ContextScope BASE_EMBEDDED {
      29             :  public:
      30     2454746 :   ContextScope(BytecodeGenerator* generator, Scope* scope,
      31      377307 :                bool should_pop_context = true)
      32             :       : generator_(generator),
      33             :         scope_(scope),
      34     2832053 :         outer_(generator_->execution_context()),
      35             :         register_(Register::current_context()),
      36             :         depth_(0),
      37     4909492 :         should_pop_context_(should_pop_context) {
      38             :     DCHECK(scope->NeedsContext() || outer_ == nullptr);
      39     2454757 :     if (outer_) {
      40      377307 :       depth_ = outer_->depth_ + 1;
      41             : 
      42             :       // Push the outer context into a new context register.
      43      754614 :       Register outer_context_reg(builder()->first_context_register().index() +
      44      377307 :                                  outer_->depth_);
      45             :       outer_->set_register(outer_context_reg);
      46      754614 :       generator_->builder()->PushContext(outer_context_reg);
      47             :     }
      48     2454757 :     generator_->set_execution_context(this);
      49     2454757 :   }
      50             : 
      51     2454762 :   ~ContextScope() {
      52     2454762 :     if (outer_ && should_pop_context_) {
      53             :       DCHECK_EQ(register_.index(), Register::current_context().index());
      54      176269 :       generator_->builder()->PopContext(outer_->reg());
      55      176269 :       outer_->set_register(register_);
      56             :     }
      57     2454762 :     generator_->set_execution_context(outer_);
      58     2454762 :   }
      59             : 
      60             :   // Returns the depth of the given |scope| for the current execution context.
      61             :   int ContextChainDepth(Scope* scope) {
      62     4358445 :     return scope_->ContextChainLength(scope);
      63             :   }
      64             : 
      65             :   // Returns the execution context at |depth| in the current context chain if it
      66             :   // is a function local execution context, otherwise returns nullptr.
      67             :   ContextScope* Previous(int depth) {
      68     4351085 :     if (depth > depth_) {
      69             :       return nullptr;
      70             :     }
      71             : 
      72             :     ContextScope* previous = this;
      73      115707 :     for (int i = depth; i > 0; --i) {
      74      115707 :       previous = previous->outer_;
      75             :     }
      76             :     return previous;
      77             :   }
      78             : 
      79             :   Register reg() const { return register_; }
      80             :   bool ShouldPopContext() { return should_pop_context_; }
      81             : 
      82             :  private:
      83      377307 :   const BytecodeArrayBuilder* builder() const { return generator_->builder(); }
      84             : 
      85      553576 :   void set_register(Register reg) { register_ = reg; }
      86             : 
      87             :   BytecodeGenerator* generator_;
      88             :   Scope* scope_;
      89             :   ContextScope* outer_;
      90             :   Register register_;
      91             :   int depth_;
      92             :   bool should_pop_context_;
      93             : };
      94             : 
      95             : // Scoped class for tracking control statements entered by the
      96             : // visitor. The pattern derives AstGraphBuilder::ControlScope.
      97             : class BytecodeGenerator::ControlScope BASE_EMBEDDED {
      98             :  public:
      99    15298114 :   explicit ControlScope(BytecodeGenerator* generator)
     100             :       : generator_(generator), outer_(generator->execution_control()),
     101    22947171 :         context_(generator->execution_context()) {
     102             :     generator_->set_execution_control(this);
     103             :   }
     104     7649064 :   virtual ~ControlScope() { generator_->set_execution_control(outer()); }
     105             : 
     106       76339 :   void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
     107       11886 :   void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
     108     2109760 :   void ReturnAccumulator() { PerformCommand(CMD_RETURN, nullptr); }
     109        4960 :   void AsyncReturnAccumulator() { PerformCommand(CMD_ASYNC_RETURN, nullptr); }
     110             :   void ReThrowAccumulator() { PerformCommand(CMD_RETHROW, nullptr); }
     111             : 
     112             :   class DeferredCommands;
     113             : 
     114             :  protected:
     115             :   enum Command {
     116             :     CMD_BREAK,
     117             :     CMD_CONTINUE,
     118             :     CMD_RETURN,
     119             :     CMD_ASYNC_RETURN,
     120             :     CMD_RETHROW
     121             :   };
     122             :   void PerformCommand(Command command, Statement* statement);
     123             :   virtual bool Execute(Command command, Statement* statement) = 0;
     124             : 
     125             :   BytecodeGenerator* generator() const { return generator_; }
     126             :   ControlScope* outer() const { return outer_; }
     127             :   ContextScope* context() const { return context_; }
     128             : 
     129             :  private:
     130             :   BytecodeGenerator* generator_;
     131             :   ControlScope* outer_;
     132             :   ContextScope* context_;
     133             : 
     134             :   DISALLOW_COPY_AND_ASSIGN(ControlScope);
     135             : };
     136             : 
     137             : // Helper class for a try-finally control scope. It can record intercepted
     138             : // control-flow commands that cause entry into a finally-block, and re-apply
     139             : // them after again leaving that block. Special tokens are used to identify
     140             : // paths going through the finally-block to dispatch after leaving the block.
     141             : class BytecodeGenerator::ControlScope::DeferredCommands final {
     142             :  public:
     143       48266 :   DeferredCommands(BytecodeGenerator* generator, Register token_register,
     144             :                    Register result_register)
     145             :       : generator_(generator),
     146             :         deferred_(generator->zone()),
     147             :         token_register_(token_register),
     148       96532 :         result_register_(result_register) {}
     149             : 
     150             :   // One recorded control-flow command.
     151             :   struct Entry {
     152             :     Command command;       // The command type being applied on this path.
     153             :     Statement* statement;  // The target statement for the command or {nullptr}.
     154             :     int token;             // A token identifying this particular path.
     155             :   };
     156             : 
     157             :   // Records a control-flow command while entering the finally-block. This also
     158             :   // generates a new dispatch token that identifies one particular path. This
     159             :   // expects the result to be in the accumulator.
     160      355844 :   void RecordCommand(Command command, Statement* statement) {
     161      177922 :     int token = static_cast<int>(deferred_.size());
     162      177922 :     deferred_.push_back({command, statement, token});
     163             : 
     164       88961 :     builder()->StoreAccumulatorInRegister(result_register_);
     165       88961 :     builder()->LoadLiteral(Smi::FromInt(token));
     166       88961 :     builder()->StoreAccumulatorInRegister(token_register_);
     167       88961 :   }
     168             : 
     169             :   // Records the dispatch token to be used to identify the re-throw path when
     170             :   // the finally-block has been entered through the exception handler. This
     171             :   // expects the exception to be in the accumulator.
     172             :   void RecordHandlerReThrowPath() {
     173             :     // The accumulator contains the exception object.
     174       48266 :     RecordCommand(CMD_RETHROW, nullptr);
     175             :   }
     176             : 
     177             :   // Records the dispatch token to be used to identify the implicit fall-through
     178             :   // path at the end of a try-block into the corresponding finally-block.
     179       96532 :   void RecordFallThroughPath() {
     180       48266 :     builder()->LoadLiteral(Smi::FromInt(-1));
     181       48266 :     builder()->StoreAccumulatorInRegister(token_register_);
     182       48266 :   }
     183             : 
     184             :   // Applies all recorded control-flow commands after the finally-block again.
     185             :   // This generates a dynamic dispatch on the token from the entry point.
     186      452374 :   void ApplyDeferredCommands() {
     187             :     // The fall-through path is covered by the default case, hence +1 here.
     188      419251 :     SwitchBuilder dispatch(builder(), static_cast<int>(deferred_.size() + 1));
     189      274452 :     for (size_t i = 0; i < deferred_.size(); ++i) {
     190             :       Entry& entry = deferred_[i];
     191      177920 :       builder()->LoadLiteral(Smi::FromInt(entry.token));
     192       88960 :       builder()->CompareOperation(Token::EQ_STRICT, token_register_);
     193       88961 :       dispatch.Case(ToBooleanMode::kAlreadyBoolean, static_cast<int>(i));
     194             :     }
     195       48266 :     dispatch.DefaultAt(static_cast<int>(deferred_.size()));
     196      274454 :     for (size_t i = 0; i < deferred_.size(); ++i) {
     197             :       Entry& entry = deferred_[i];
     198       88961 :       dispatch.SetCaseTarget(static_cast<int>(i));
     199       88961 :       builder()->LoadAccumulatorWithRegister(result_register_);
     200      177922 :       execution_control()->PerformCommand(entry.command, entry.statement);
     201             :     }
     202       48266 :     dispatch.SetCaseTarget(static_cast<int>(deferred_.size()));
     203       48266 :   }
     204             : 
     205      678562 :   BytecodeArrayBuilder* builder() { return generator_->builder(); }
     206       88961 :   ControlScope* execution_control() { return generator_->execution_control(); }
     207             : 
     208             :  private:
     209             :   BytecodeGenerator* generator_;
     210             :   ZoneVector<Entry> deferred_;
     211             :   Register token_register_;
     212             :   Register result_register_;
     213             : };
     214             : 
     215             : // Scoped class for dealing with control flow reaching the function level.
     216     2077456 : class BytecodeGenerator::ControlScopeForTopLevel final
     217             :     : public BytecodeGenerator::ControlScope {
     218             :  public:
     219             :   explicit ControlScopeForTopLevel(BytecodeGenerator* generator)
     220     2077450 :       : ControlScope(generator) {}
     221             : 
     222             :  protected:
     223     2158196 :   bool Execute(Command command, Statement* statement) override {
     224     2158196 :     switch (command) {
     225             :       case CMD_BREAK:  // We should never see break/continue in top-level.
     226             :       case CMD_CONTINUE:
     227           0 :         UNREACHABLE();
     228             :       case CMD_RETURN:
     229     2158202 :         generator()->BuildReturn();
     230     2109760 :         return true;
     231             :       case CMD_ASYNC_RETURN:
     232        4960 :         generator()->BuildAsyncReturn();
     233        4960 :         return true;
     234             :       case CMD_RETHROW:
     235             :         generator()->BuildReThrow();
     236       43488 :         return true;
     237             :     }
     238             :     return false;
     239             :   }
     240             : };
     241             : 
     242             : // Scoped class for enabling break inside blocks and switch blocks.
     243     5202032 : class BytecodeGenerator::ControlScopeForBreakable final
     244             :     : public BytecodeGenerator::ControlScope {
     245             :  public:
     246             :   ControlScopeForBreakable(BytecodeGenerator* generator,
     247             :                            BreakableStatement* statement,
     248             :                            BreakableControlFlowBuilder* control_builder)
     249             :       : ControlScope(generator),
     250             :         statement_(statement),
     251     5202031 :         control_builder_(control_builder) {}
     252             : 
     253             :  protected:
     254      753923 :   bool Execute(Command command, Statement* statement) override {
     255      753923 :     if (statement != statement_) return false;
     256       43477 :     switch (command) {
     257             :       case CMD_BREAK:
     258       43477 :         control_builder_->Break();
     259       43477 :         return true;
     260             :       case CMD_CONTINUE:
     261             :       case CMD_RETURN:
     262             :       case CMD_ASYNC_RETURN:
     263             :       case CMD_RETHROW:
     264             :         break;
     265             :     }
     266             :     return false;
     267             :   }
     268             : 
     269             :  private:
     270             :   Statement* statement_;
     271             :   BreakableControlFlowBuilder* control_builder_;
     272             : };
     273             : 
     274             : // Scoped class for enabling 'break' and 'continue' in iteration
     275             : // constructs, e.g. do...while, while..., for...
     276             : class BytecodeGenerator::ControlScopeForIteration final
     277             :     : public BytecodeGenerator::ControlScope {
     278             :  public:
     279             :   ControlScopeForIteration(BytecodeGenerator* generator,
     280             :                            IterationStatement* statement,
     281             :                            LoopBuilder* loop_builder)
     282             :       : ControlScope(generator),
     283             :         statement_(statement),
     284      193044 :         loop_builder_(loop_builder) {
     285      193044 :     generator->loop_depth_++;
     286             :   }
     287      193044 :   ~ControlScopeForIteration() { generator()->loop_depth_--; }
     288             : 
     289             :  protected:
     290       99126 :   bool Execute(Command command, Statement* statement) override {
     291       99126 :     if (statement != statement_) return false;
     292       44748 :     switch (command) {
     293             :       case CMD_BREAK:
     294       32862 :         loop_builder_->Break();
     295       32862 :         return true;
     296             :       case CMD_CONTINUE:
     297       11886 :         loop_builder_->Continue();
     298       11886 :         return true;
     299             :       case CMD_RETURN:
     300             :       case CMD_ASYNC_RETURN:
     301             :       case CMD_RETHROW:
     302             :         break;
     303             :     }
     304             :     return false;
     305             :   }
     306             : 
     307             :  private:
     308             :   Statement* statement_;
     309             :   LoopBuilder* loop_builder_;
     310             : };
     311             : 
     312             : // Scoped class for enabling 'throw' in try-catch constructs.
     313      128266 : class BytecodeGenerator::ControlScopeForTryCatch final
     314             :     : public BytecodeGenerator::ControlScope {
     315             :  public:
     316             :   ControlScopeForTryCatch(BytecodeGenerator* generator,
     317             :                           TryCatchBuilder* try_catch_builder)
     318      128266 :       : ControlScope(generator) {}
     319             : 
     320             :  protected:
     321       50260 :   bool Execute(Command command, Statement* statement) override {
     322       50260 :     switch (command) {
     323             :       case CMD_BREAK:
     324             :       case CMD_CONTINUE:
     325             :       case CMD_RETURN:
     326             :       case CMD_ASYNC_RETURN:
     327             :         break;
     328             :       case CMD_RETHROW:
     329        4778 :         generator()->BuildReThrow();
     330        4778 :         return true;
     331             :     }
     332             :     return false;
     333             :   }
     334             : };
     335             : 
     336             : // Scoped class for enabling control flow through try-finally constructs.
     337       48266 : class BytecodeGenerator::ControlScopeForTryFinally final
     338             :     : public BytecodeGenerator::ControlScope {
     339             :  public:
     340             :   ControlScopeForTryFinally(BytecodeGenerator* generator,
     341             :                             TryFinallyBuilder* try_finally_builder,
     342             :                             DeferredCommands* commands)
     343             :       : ControlScope(generator),
     344             :         try_finally_builder_(try_finally_builder),
     345       48266 :         commands_(commands) {}
     346             : 
     347             :  protected:
     348       40695 :   bool Execute(Command command, Statement* statement) override {
     349       40695 :     switch (command) {
     350             :       case CMD_BREAK:
     351             :       case CMD_CONTINUE:
     352             :       case CMD_RETURN:
     353             :       case CMD_ASYNC_RETURN:
     354             :       case CMD_RETHROW:
     355       40695 :         commands_->RecordCommand(command, statement);
     356       40695 :         try_finally_builder_->LeaveTry();
     357       40695 :         return true;
     358             :     }
     359             :     return false;
     360             :   }
     361             : 
     362             :  private:
     363             :   TryFinallyBuilder* try_finally_builder_;
     364             :   DeferredCommands* commands_;
     365             : };
     366             : 
     367     2291905 : void BytecodeGenerator::ControlScope::PerformCommand(Command command,
     368     2355328 :                                                      Statement* statement) {
     369     3102211 :   ControlScope* current = this;
     370     2505669 :   ContextScope* context = generator()->execution_context();
     371             :   // Pop context to the expected depth but do not pop the outermost context.
     372     2404389 :   if (context != current->context() && context->ShouldPopContext()) {
     373         103 :     generator()->builder()->PopContext(current->context()->reg());
     374             :   }
     375      810306 :   do {
     376     3102212 :     if (current->Execute(command, statement)) {
     377     2291906 :       return;
     378             :     }
     379             :     current = current->outer();
     380      911586 :     if (current->context() != context && context->ShouldPopContext()) {
     381             :       // Pop context to the expected depth.
     382             :       // TODO(rmcilroy): Only emit a single context pop.
     383       63423 :       generator()->builder()->PopContext(current->context()->reg());
     384             :     }
     385             :   } while (current != nullptr);
     386           0 :   UNREACHABLE();
     387             : }
     388             : 
     389             : class BytecodeGenerator::RegisterAllocationScope {
     390             :  public:
     391             :   explicit RegisterAllocationScope(BytecodeGenerator* generator)
     392             :       : generator_(generator),
     393             :         outer_next_register_index_(
     394   149355592 :             generator->register_allocator()->next_register_index()) {}
     395             : 
     396    74677532 :   virtual ~RegisterAllocationScope() {
     397             :     generator_->register_allocator()->ReleaseRegisters(
     398    74677532 :         outer_next_register_index_);
     399    74677509 :   }
     400             : 
     401             :  private:
     402             :   BytecodeGenerator* generator_;
     403             :   int outer_next_register_index_;
     404             : 
     405             :   DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
     406             : };
     407             : 
     408             : // Scoped base class for determining how the result of an expression will be
     409             : // used.
     410             : class BytecodeGenerator::ExpressionResultScope {
     411             :  public:
     412    43712085 :   ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
     413             :       : generator_(generator),
     414             :         outer_(generator->execution_result()),
     415             :         allocator_(generator),
     416             :         kind_(kind),
     417   131136255 :         type_hint_(TypeHint::kAny) {
     418             :     generator_->set_execution_result(this);
     419             :   }
     420             : 
     421    87424240 :   virtual ~ExpressionResultScope() {
     422    43712120 :     generator_->set_execution_result(outer_);
     423           0 :   }
     424             : 
     425             :   bool IsEffect() const { return kind_ == Expression::kEffect; }
     426             :   bool IsValue() const { return kind_ == Expression::kValue; }
     427             :   bool IsTest() const { return kind_ == Expression::kTest; }
     428             : 
     429             :   TestResultScope* AsTest() {
     430             :     DCHECK(IsTest());
     431             :     return reinterpret_cast<TestResultScope*>(this);
     432             :   }
     433             : 
     434             :   // Specify expression always returns a Boolean result value.
     435             :   void SetResultIsBoolean() {
     436             :     DCHECK(type_hint_ == TypeHint::kAny);
     437     1938606 :     type_hint_ = TypeHint::kBoolean;
     438             :   }
     439             : 
     440             :   TypeHint type_hint() const { return type_hint_; }
     441             : 
     442             :  private:
     443             :   BytecodeGenerator* generator_;
     444             :   ExpressionResultScope* outer_;
     445             :   RegisterAllocationScope allocator_;
     446             :   Expression::Context kind_;
     447             :   TypeHint type_hint_;
     448             : 
     449             :   DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
     450             : };
     451             : 
     452             : // Scoped class used when the result of the current expression is not
     453             : // expected to produce a result.
     454     9526933 : class BytecodeGenerator::EffectResultScope final
     455             :     : public ExpressionResultScope {
     456             :  public:
     457             :   explicit EffectResultScope(BytecodeGenerator* generator)
     458     9526920 :       : ExpressionResultScope(generator, Expression::kEffect) {}
     459             : };
     460             : 
     461             : // Scoped class used when the result of the current expression to be
     462             : // evaluated should go into the interpreter's accumulator.
     463    32132375 : class BytecodeGenerator::ValueResultScope final : public ExpressionResultScope {
     464             :  public:
     465             :   explicit ValueResultScope(BytecodeGenerator* generator)
     466    32132352 :       : ExpressionResultScope(generator, Expression::kValue) {}
     467             : };
     468             : 
     469             : // Scoped class used when the result of the current expression to be
     470             : // evaluated is only tested with jumps to two branches.
     471     2052812 : class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
     472             :  public:
     473             :   TestResultScope(BytecodeGenerator* generator, BytecodeLabels* then_labels,
     474             :                   BytecodeLabels* else_labels, TestFallthrough fallthrough)
     475             :       : ExpressionResultScope(generator, Expression::kTest),
     476             :         then_labels_(then_labels),
     477             :         else_labels_(else_labels),
     478             :         fallthrough_(fallthrough),
     479     2052813 :         result_consumed_by_test_(false) {}
     480             : 
     481             :   // Used when code special cases for TestResultScope and consumes any
     482             :   // possible value by testing and jumping to a then/else label.
     483             :   void SetResultConsumedByTest() {
     484      705263 :     result_consumed_by_test_ = true;
     485             :   }
     486             :   bool result_consumed_by_test() { return result_consumed_by_test_; }
     487             : 
     488       67649 :   BytecodeLabel* NewThenLabel() { return then_labels_->New(); }
     489      106495 :   BytecodeLabel* NewElseLabel() { return else_labels_->New(); }
     490             : 
     491             :   BytecodeLabels* then_labels() const { return then_labels_; }
     492             :   BytecodeLabels* else_labels() const { return else_labels_; }
     493             : 
     494             :   TestFallthrough fallthrough() const { return fallthrough_; }
     495             :   TestFallthrough inverted_fallthrough() const {
     496      339281 :     switch (fallthrough_) {
     497             :       case TestFallthrough::kThen:
     498             :         return TestFallthrough::kElse;
     499             :       case TestFallthrough::kElse:
     500             :         return TestFallthrough::kThen;
     501             :       default:
     502             :         return TestFallthrough::kNone;
     503             :     }
     504             :   }
     505             : 
     506             :  private:
     507             :   BytecodeLabels* then_labels_;
     508             :   BytecodeLabels* else_labels_;
     509             :   TestFallthrough fallthrough_;
     510             :   bool result_consumed_by_test_;
     511             : 
     512             :   DISALLOW_COPY_AND_ASSIGN(TestResultScope);
     513             : };
     514             : 
     515             : // Used to build a list of global declaration initial value pairs.
     516             : class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
     517             :  public:
     518     2154835 :   explicit GlobalDeclarationsBuilder(Zone* zone)
     519             :       : declarations_(0, zone),
     520             :         constant_pool_entry_(0),
     521     2154835 :         has_constant_pool_entry_(false) {}
     522             : 
     523             :   void AddFunctionDeclaration(const AstRawString* name, FeedbackSlot slot,
     524             :                               FeedbackSlot literal_slot,
     525             :                               FunctionLiteral* func) {
     526             :     DCHECK(!slot.IsInvalid());
     527      305260 :     declarations_.push_back(Declaration(name, slot, literal_slot, func));
     528             :   }
     529             : 
     530             :   void AddUndefinedDeclaration(const AstRawString* name, FeedbackSlot slot) {
     531             :     DCHECK(!slot.IsInvalid());
     532     1179370 :     declarations_.push_back(Declaration(name, slot, nullptr));
     533             :   }
     534             : 
     535     1334114 :   Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) {
     536             :     DCHECK(has_constant_pool_entry_);
     537             :     int array_index = 0;
     538             :     Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray(
     539      232116 :         static_cast<int>(declarations_.size() * 4), TENURED);
     540      897059 :     for (const Declaration& declaration : declarations_) {
     541      742315 :       FunctionLiteral* func = declaration.func;
     542             :       Handle<Object> initial_value;
     543      742315 :       if (func == nullptr) {
     544             :         initial_value = info->isolate()->factory()->undefined_value();
     545             :       } else {
     546             :         initial_value =
     547      152630 :             Compiler::GetSharedFunctionInfo(func, info->script(), info);
     548             :       }
     549             : 
     550             :       // Return a null handle if any initial values can't be created. Caller
     551             :       // will set stack overflow.
     552      742315 :       if (initial_value.is_null()) return Handle<FixedArray>();
     553             : 
     554     2226945 :       data->set(array_index++, *declaration.name->string());
     555      742315 :       data->set(array_index++, Smi::FromInt(declaration.slot.ToInt()));
     556             :       Object* undefined_or_literal_slot;
     557      742315 :       if (declaration.literal_slot.IsInvalid()) {
     558      589685 :         undefined_or_literal_slot = info->isolate()->heap()->undefined_value();
     559             :       } else {
     560             :         undefined_or_literal_slot =
     561             :             Smi::FromInt(declaration.literal_slot.ToInt());
     562             :       }
     563     1484630 :       data->set(array_index++, undefined_or_literal_slot);
     564     1484630 :       data->set(array_index++, *initial_value);
     565             :     }
     566       77372 :     return data;
     567             :   }
     568             : 
     569             :   size_t constant_pool_entry() {
     570             :     DCHECK(has_constant_pool_entry_);
     571             :     return constant_pool_entry_;
     572             :   }
     573             : 
     574             :   void set_constant_pool_entry(size_t constant_pool_entry) {
     575             :     DCHECK(!empty());
     576             :     DCHECK(!has_constant_pool_entry_);
     577       77372 :     constant_pool_entry_ = constant_pool_entry;
     578       77372 :     has_constant_pool_entry_ = true;
     579             :   }
     580             : 
     581             :   bool empty() { return declarations_.empty(); }
     582             : 
     583             :  private:
     584             :   struct Declaration {
     585     4309670 :     Declaration() : slot(FeedbackSlot::Invalid()), func(nullptr) {}
     586             :     Declaration(const AstRawString* name, FeedbackSlot slot,
     587             :                 FeedbackSlot literal_slot, FunctionLiteral* func)
     588      152630 :         : name(name), slot(slot), literal_slot(literal_slot), func(func) {}
     589             :     Declaration(const AstRawString* name, FeedbackSlot slot,
     590             :                 FunctionLiteral* func)
     591             :         : name(name),
     592             :           slot(slot),
     593             :           literal_slot(FeedbackSlot::Invalid()),
     594      589685 :           func(func) {}
     595             : 
     596             :     const AstRawString* name;
     597             :     FeedbackSlot slot;
     598             :     FeedbackSlot literal_slot;
     599             :     FunctionLiteral* func;
     600             :   };
     601             :   ZoneVector<Declaration> declarations_;
     602             :   size_t constant_pool_entry_;
     603             :   bool has_constant_pool_entry_;
     604             : };
     605             : 
     606             : class BytecodeGenerator::CurrentScope final {
     607             :  public:
     608     5315477 :   CurrentScope(BytecodeGenerator* generator, Scope* scope)
     609             :       : generator_(generator), outer_scope_(generator->current_scope()) {
     610     5315477 :     if (scope != nullptr) {
     611             :       generator_->set_current_scope(scope);
     612             :     }
     613             :   }
     614             :   ~CurrentScope() {
     615     5315478 :     if (outer_scope_ != generator_->current_scope()) {
     616             :       generator_->set_current_scope(outer_scope_);
     617             :     }
     618             :   }
     619             : 
     620             :  private:
     621             :   BytecodeGenerator* generator_;
     622             :   Scope* outer_scope_;
     623             : };
     624             : 
     625    22852043 : BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
     626             :     : zone_(info->zone()),
     627             :       builder_(new (zone()) BytecodeArrayBuilder(
     628             :           info->isolate(), info->zone(), info->num_parameters_including_this(),
     629     2077454 :           info->scope()->MaxNestedContextChainLength(),
     630     2077460 :           info->scope()->num_stack_slots(), info->literal(),
     631     2077462 :           info->SourcePositionRecordingMode())),
     632             :       info_(info),
     633     2077462 :       ast_string_constants_(info->isolate()->ast_string_constants()),
     634     2077462 :       closure_scope_(info->scope()),
     635     2077464 :       current_scope_(info->scope()),
     636     2077464 :       globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
     637             :       global_declarations_(0, info->zone()),
     638             :       function_literals_(0, info->zone()),
     639             :       native_function_literals_(0, info->zone()),
     640             :       object_literals_(0, info->zone()),
     641             :       array_literals_(0, info->zone()),
     642             :       execution_control_(nullptr),
     643             :       execution_context_(nullptr),
     644             :       execution_result_(nullptr),
     645     2077458 :       generator_resume_points_(info->literal()->suspend_count(), info->zone()),
     646             :       generator_state_(),
     647    24929514 :       loop_depth_(0) {
     648             :   DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
     649     2077457 : }
     650             : 
     651     6232258 : Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
     652     2077422 :   AllocateDeferredConstants(isolate);
     653     2077418 :   if (HasStackOverflow()) return Handle<BytecodeArray>();
     654     2077418 :   return builder()->ToBytecodeArray(isolate);
     655             : }
     656             : 
     657     9551305 : void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) {
     658             :   // Build global declaration pair arrays.
     659     4309572 :   for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
     660             :     Handle<FixedArray> declarations =
     661       77372 :         globals_builder->AllocateDeclarations(info());
     662       77372 :     if (declarations.is_null()) return SetStackOverflow();
     663             :     builder()->SetDeferredConstantPoolEntry(
     664       77372 :         globals_builder->constant_pool_entry(), declarations);
     665             :   }
     666             : 
     667             :   // Find or build shared function infos.
     668     7589264 :   for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
     669             :     FunctionLiteral* expr = literal.first;
     670             :     Handle<SharedFunctionInfo> shared_info =
     671     3434433 :         Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
     672     3434436 :     if (shared_info.is_null()) return SetStackOverflow();
     673     3434436 :     builder()->SetDeferredConstantPoolEntry(literal.second, shared_info);
     674             :   }
     675             : 
     676             :   // Find or build shared function infos for the native function templates.
     677     4157317 :   for (std::pair<NativeFunctionLiteral*, size_t> literal :
     678        2483 :        native_function_literals_) {
     679        4966 :     NativeFunctionLiteral* expr = literal.first;
     680             :     Handle<SharedFunctionInfo> shared_info =
     681             :         Compiler::GetSharedFunctionInfoForNative(expr->extension(),
     682        2483 :                                                  expr->name());
     683        2483 :     if (shared_info.is_null()) return SetStackOverflow();
     684        2483 :     builder()->SetDeferredConstantPoolEntry(literal.second, shared_info);
     685             :   }
     686             : 
     687             :   // Build object literal constant properties
     688     4451167 :   for (std::pair<ObjectLiteral*, size_t> literal : object_literals_) {
     689      296333 :     ObjectLiteral* object_literal = literal.first;
     690      296333 :     if (object_literal->properties_count() > 0) {
     691             :       // If constant properties is an empty fixed array, we've already added it
     692             :       // to the constant pool when visiting the object literal.
     693             :       Handle<BoilerplateDescription> constant_properties =
     694             :           object_literal->GetOrBuildConstantProperties(isolate);
     695             : 
     696             :       builder()->SetDeferredConstantPoolEntry(literal.second,
     697      296333 :                                               constant_properties);
     698             :     }
     699             :   }
     700             : 
     701             :   // Build array literal constant elements
     702     4306296 :   for (std::pair<ArrayLiteral*, size_t> literal : array_literals_) {
     703             :     ArrayLiteral* array_literal = literal.first;
     704             :     Handle<ConstantElementsPair> constant_elements =
     705             :         array_literal->GetOrBuildConstantElements(isolate);
     706      151462 :     builder()->SetDeferredConstantPoolEntry(literal.second, constant_elements);
     707             :   }
     708             : }
     709             : 
     710    10588409 : void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
     711             :   DisallowHeapAllocation no_allocation;
     712             :   DisallowHandleAllocation no_handles;
     713             :   DisallowHandleDereference no_deref;
     714             : 
     715             :   InitializeAstVisitor(stack_limit);
     716             : 
     717             :   // Initialize the incoming context.
     718     2077439 :   ContextScope incoming_context(this, closure_scope(), false);
     719             : 
     720             :   // Initialize control scope.
     721             :   ControlScopeForTopLevel control(this);
     722             : 
     723     2077454 :   RegisterAllocationScope register_scope(this);
     724             : 
     725     4154908 :   if (IsResumableFunction(info()->literal()->kind())) {
     726       10819 :     generator_state_ = register_allocator()->NewRegister();
     727       10819 :     VisitGeneratorPrologue();
     728             :   }
     729             : 
     730     2077451 :   if (closure_scope()->NeedsContext()) {
     731             :     // Push a new inner context scope for the function.
     732      201038 :     BuildNewLocalActivationContext();
     733      201038 :     ContextScope local_function_context(this, closure_scope(), false);
     734      201038 :     BuildLocalActivationContextInitialization();
     735      201038 :     GenerateBytecodeBody();
     736             :   } else {
     737     1876413 :     GenerateBytecodeBody();
     738             :   }
     739             : 
     740             :   // In generator functions, we may not have visited every yield in the AST
     741             :   // since we skip some obviously dead code. Hence the generated bytecode may
     742             :   // contain jumps to unbound labels (resume points that will never be used).
     743             :   // We bind these now.
     744     4174879 :   for (auto& label : generator_resume_points_) {
     745       20109 :     if (!label.is_bound()) builder()->Bind(&label);
     746             :   }
     747             : 
     748             :   // Emit an implicit return instruction in case control flow can fall off the
     749             :   // end of the function without an explicit return being present on all paths.
     750     2077454 :   if (builder()->RequiresImplicitReturn()) {
     751      443138 :     builder()->LoadUndefined();
     752      443138 :     BuildReturn();
     753             :   }
     754     2077456 :   DCHECK(!builder()->RequiresImplicitReturn());
     755     2077456 : }
     756             : 
     757    18697375 : void BytecodeGenerator::GenerateBytecodeBody() {
     758             :   // Build the arguments object if it is used.
     759     2077438 :   VisitArgumentsObject(closure_scope()->arguments());
     760             : 
     761             :   // Build rest arguments array if it is used.
     762             :   Variable* rest_parameter = closure_scope()->rest_parameter();
     763     2077438 :   VisitRestArgumentsArray(rest_parameter);
     764             : 
     765             :   // Build assignment to {.this_function} variable if it is used.
     766     2077440 :   VisitThisFunctionVariable(closure_scope()->this_function_var());
     767             : 
     768             :   // Build assignment to {new.target} variable if it is used.
     769     2077444 :   VisitNewTargetVariable(closure_scope()->new_target_var());
     770             : 
     771             :   // Emit tracing call if requested to do so.
     772     2077450 :   if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter);
     773             : 
     774             :   // Emit type profile call.
     775     2077450 :   if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) {
     776             :     int num_parameters = closure_scope()->num_parameters();
     777         186 :     for (int i = 0; i < num_parameters; i++) {
     778          91 :       Register parameter(builder()->Parameter(i));
     779          91 :       builder()->LoadAccumulatorWithRegister(parameter).CollectTypeProfile(
     780         182 :           closure_scope()->parameter(i)->initializer_position());
     781             :     }
     782             :   }
     783             : 
     784             :   // Visit declarations within the function scope.
     785     2077449 :   VisitDeclarations(closure_scope()->declarations());
     786             : 
     787             :   // Emit initializing assignments for module namespace imports (if any).
     788     2077442 :   VisitModuleNamespaceImports();
     789             : 
     790             :   // Perform a stack-check before the body.
     791     4154896 :   builder()->StackCheck(info()->literal()->start_position());
     792             : 
     793             :   // Visit statements in the function body.
     794     2077452 :   VisitStatements(info()->literal()->body());
     795     2077460 : }
     796             : 
     797       11853 : void BytecodeGenerator::BuildIndexedJump(Register index, size_t start_index,
     798             :                                          size_t size,
     799       21209 :                                          ZoneVector<BytecodeLabel>& targets) {
     800             :   // TODO(neis): Optimize this by using a proper jump table.
     801             :   DCHECK_LE(start_index + size, targets.size());
     802       33062 :   for (size_t i = start_index; i < start_index + size; i++) {
     803             :     builder()
     804       42418 :         ->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
     805       21209 :         .CompareOperation(Token::Value::EQ_STRICT, index)
     806       42418 :         .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &(targets[i]));
     807             :   }
     808       11853 :   BuildAbort(BailoutReason::kInvalidJumpTableIndex);
     809       11853 : }
     810             : 
     811      197080 : void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
     812        3102 :                                              LoopBuilder* loop_builder) {
     813             :   // Recall that stmt->yield_count() is always zero inside ordinary
     814             :   // (i.e. non-generator) functions.
     815      192740 :   if (stmt->suspend_count() == 0) {
     816      191706 :     loop_builder->LoopHeader();
     817             :   } else {
     818             :     // Collect all labels for generator resume points within the loop (if any)
     819             :     // so that they can be bound to the loop header below. Also create fresh
     820             :     // labels for these resume points, to be used inside the loop.
     821             :     ZoneVector<BytecodeLabel> resume_points_in_loop(zone());
     822        1034 :     size_t first_yield = stmt->first_suspend_id();
     823             :     DCHECK_LE(first_yield + stmt->suspend_count(),
     824             :               generator_resume_points_.size());
     825        4544 :     for (size_t id = first_yield; id < first_yield + stmt->suspend_count();
     826             :          id++) {
     827        2476 :       auto& label = generator_resume_points_[id];
     828        1238 :       resume_points_in_loop.push_back(label);
     829        1238 :       generator_resume_points_[id] = BytecodeLabel();
     830             :     }
     831             : 
     832        1034 :     loop_builder->LoopHeader(&resume_points_in_loop);
     833             : 
     834             :     // If we are not resuming, fall through to loop body.
     835             :     // If we are resuming, perform state dispatch.
     836             :     BytecodeLabel not_resuming;
     837             :     builder()
     838        1034 :         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
     839        1034 :         .CompareOperation(Token::Value::EQ_STRICT, generator_state_)
     840        1034 :         .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &not_resuming);
     841             :     BuildIndexedJump(generator_state_, first_yield, stmt->suspend_count(),
     842        2068 :                      generator_resume_points_);
     843        1034 :     builder()->Bind(&not_resuming);
     844             :   }
     845      192740 : }
     846             : 
     847       43276 : void BytecodeGenerator::VisitGeneratorPrologue() {
     848             :   // The generator resume trampoline abuses the new.target register both to
     849             :   // indicate that this is a resume call and to pass in the generator object.
     850             :   // In ordinary calls, new.target is always undefined because generator
     851             :   // functions are non-constructable.
     852       10819 :   Register generator_object = Register::new_target();
     853             :   BytecodeLabel regular_call;
     854             :   builder()
     855       10819 :       ->LoadAccumulatorWithRegister(generator_object)
     856       10819 :       .JumpIfUndefined(&regular_call);
     857             : 
     858             :   // This is a resume call. Restore the current context and the registers, then
     859             :   // perform state dispatch.
     860       10819 :   Register dummy = register_allocator()->NewRegister();
     861             :   builder()
     862       10819 :       ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object)
     863       10819 :       .PushContext(dummy)
     864       10819 :       .ResumeGenerator(generator_object)
     865       10819 :       .StoreAccumulatorInRegister(generator_state_);
     866             :   BuildIndexedJump(generator_state_, 0, generator_resume_points_.size(),
     867       21638 :                    generator_resume_points_);
     868             : 
     869             :   builder()
     870       10819 :       ->Bind(&regular_call)
     871       10819 :       .LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
     872       10819 :       .StoreAccumulatorInRegister(generator_state_);
     873             :   // This is a regular call. Fall through to the ordinary function prologue,
     874             :   // after which we will run into the generator object creation and other extra
     875             :   // code inserted by the parser.
     876       10819 : }
     877             : 
     878    10410266 : void BytecodeGenerator::VisitBlock(Block* stmt) {
     879             :   // Visit declarations and statements.
     880             :   CurrentScope current_scope(this, stmt->scope());
     881     5366789 :   if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
     882       43950 :     BuildNewLocalBlockContext(stmt->scope());
     883       43950 :     ContextScope scope(this, stmt->scope());
     884       43950 :     VisitBlockDeclarationsAndStatements(stmt);
     885             :   } else {
     886     5139208 :     VisitBlockDeclarationsAndStatements(stmt);
     887             :   }
     888     5183159 : }
     889             : 
     890    10366316 : void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
     891             :   BlockBuilder block_builder(builder());
     892             :   ControlScopeForBreakable execution_control(this, stmt, &block_builder);
     893     5183158 :   if (stmt->scope() != nullptr) {
     894      183631 :     VisitDeclarations(stmt->scope()->declarations());
     895             :   }
     896     5183158 :   VisitStatements(stmt->statements());
     897     5183159 :   if (stmt->labels() != nullptr) block_builder.EndBlock();
     898     5183159 : }
     899             : 
     900     5149734 : void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
     901     4925243 :   Variable* variable = decl->proxy()->var();
     902     3582253 :   switch (variable->location()) {
     903             :     case VariableLocation::UNALLOCATED: {
     904             :       DCHECK(!variable->binding_needs_init());
     905             :       FeedbackSlot slot = decl->proxy()->VariableFeedbackSlot();
     906             :       globals_builder()->AddUndefinedDeclaration(variable->raw_name(), slot);
     907             :       break;
     908             :     }
     909             :     case VariableLocation::LOCAL:
     910     1535082 :       if (variable->binding_needs_init()) {
     911      223950 :         Register destination(builder()->Local(variable->index()));
     912      223950 :         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
     913             :       }
     914             :       break;
     915             :     case VariableLocation::PARAMETER:
     916         597 :       if (variable->binding_needs_init()) {
     917           0 :         Register destination(builder()->Parameter(variable->index()));
     918           0 :         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
     919             :       }
     920             :       break;
     921             :     case VariableLocation::CONTEXT:
     922     1166059 :       if (variable->binding_needs_init()) {
     923             :         DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
     924      239677 :         builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
     925      239677 :                                                   variable->index(), 0);
     926             :       }
     927             :       break;
     928             :     case VariableLocation::LOOKUP: {
     929             :       DCHECK_EQ(VAR, variable->mode());
     930             :       DCHECK(!variable->binding_needs_init());
     931             : 
     932      289678 :       Register name = register_allocator()->NewRegister();
     933             : 
     934             :       builder()
     935      289678 :           ->LoadLiteral(variable->raw_name())
     936      289678 :           .StoreAccumulatorInRegister(name)
     937      289678 :           .CallRuntime(Runtime::kDeclareEvalVar, name);
     938             :       break;
     939             :     }
     940             :     case VariableLocation::MODULE:
     941        1841 :       if (variable->IsExport() && variable->binding_needs_init()) {
     942         541 :         builder()->LoadTheHole();
     943             :         BuildVariableAssignment(variable, Token::INIT, FeedbackSlot::Invalid(),
     944         541 :                                 HoleCheckMode::kElided);
     945             :       }
     946             :       // Nothing to do for imports.
     947             :       break;
     948             :   }
     949     3582253 : }
     950             : 
     951     2097485 : void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
     952     1364545 :   Variable* variable = decl->proxy()->var();
     953             :   DCHECK(variable->mode() == LET || variable->mode() == VAR);
     954      722700 :   switch (variable->location()) {
     955             :     case VariableLocation::UNALLOCATED: {
     956             :       FeedbackSlot slot = decl->proxy()->VariableFeedbackSlot();
     957             :       globals_builder()->AddFunctionDeclaration(
     958             :           variable->raw_name(), slot, decl->fun()->LiteralFeedbackSlot(),
     959             :           decl->fun());
     960             :       break;
     961             :     }
     962             :     case VariableLocation::PARAMETER:
     963             :     case VariableLocation::LOCAL: {
     964       80485 :       VisitForAccumulatorValue(decl->fun());
     965             :       BuildVariableAssignment(variable, Token::INIT, FeedbackSlot::Invalid(),
     966       80485 :                               HoleCheckMode::kElided);
     967       80485 :       break;
     968             :     }
     969             :     case VariableLocation::CONTEXT: {
     970             :       DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
     971      478975 :       VisitForAccumulatorValue(decl->fun());
     972             :       builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
     973      478975 :                                   0);
     974      478975 :       break;
     975             :     }
     976             :     case VariableLocation::LOOKUP: {
     977       10240 :       RegisterList args = register_allocator()->NewRegisterList(2);
     978             :       builder()
     979       10240 :           ->LoadLiteral(variable->raw_name())
     980       10240 :           .StoreAccumulatorInRegister(args[0]);
     981       10240 :       VisitForAccumulatorValue(decl->fun());
     982       10240 :       builder()->StoreAccumulatorInRegister(args[1]).CallRuntime(
     983       10240 :           Runtime::kDeclareEvalFunction, args);
     984             :       break;
     985             :     }
     986             :     case VariableLocation::MODULE:
     987             :       DCHECK_EQ(variable->mode(), LET);
     988             :       DCHECK(variable->IsExport());
     989         370 :       VisitForAccumulatorValue(decl->fun());
     990             :       BuildVariableAssignment(variable, Token::INIT, FeedbackSlot::Invalid(),
     991         370 :                               HoleCheckMode::kElided);
     992         370 :       break;
     993             :   }
     994      722700 : }
     995             : 
     996     2078735 : void BytecodeGenerator::VisitModuleNamespaceImports() {
     997     4153748 :   if (!closure_scope()->is_module_scope()) return;
     998             : 
     999             :   RegisterAllocationScope register_scope(this);
    1000        1134 :   Register module_request = register_allocator()->NewRegister();
    1001             : 
    1002        1134 :   ModuleDescriptor* descriptor = closure_scope()->AsModuleScope()->module();
    1003        2348 :   for (auto entry : descriptor->namespace_imports()) {
    1004             :     builder()
    1005         160 :         ->LoadLiteral(Smi::FromInt(entry->module_request))
    1006          80 :         .StoreAccumulatorInRegister(module_request)
    1007          80 :         .CallRuntime(Runtime::kGetModuleNamespace, module_request);
    1008         160 :     Variable* var = closure_scope()->LookupLocal(entry->local_name);
    1009             :     DCHECK_NOT_NULL(var);
    1010             :     BuildVariableAssignment(var, Token::INIT, FeedbackSlot::Invalid(),
    1011          80 :                             HoleCheckMode::kElided);
    1012        1134 :   }
    1013             : }
    1014             : 
    1015     5063754 : void BytecodeGenerator::VisitDeclarations(Declaration::List* declarations) {
    1016             :   RegisterAllocationScope register_scope(this);
    1017             :   DCHECK(globals_builder()->empty());
    1018     8827103 :   for (Declaration* decl : *declarations) {
    1019             :     RegisterAllocationScope register_scope(this);
    1020     4304953 :     Visit(decl);
    1021     4304953 :   }
    1022     4444778 :   if (globals_builder()->empty()) return;
    1023             : 
    1024             :   globals_builder()->set_constant_pool_entry(
    1025       77372 :       builder()->AllocateDeferredConstantPoolEntry());
    1026       77372 :   int encoded_flags = info()->GetDeclareGlobalsFlags();
    1027             : 
    1028             :   // Emit code to declare globals.
    1029       77372 :   RegisterList args = register_allocator()->NewRegisterList(3);
    1030             :   builder()
    1031      154744 :       ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
    1032       77372 :       .StoreAccumulatorInRegister(args[0])
    1033       77372 :       .LoadLiteral(Smi::FromInt(encoded_flags))
    1034       77372 :       .StoreAccumulatorInRegister(args[1])
    1035      154744 :       .MoveRegister(Register::function_closure(), args[2])
    1036       77372 :       .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, args);
    1037             : 
    1038             :   // Push and reset globals builder.
    1039      154744 :   global_declarations_.push_back(globals_builder());
    1040       77372 :   globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
    1041             : }
    1042             : 
    1043     7374155 : void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
    1044    42681152 :   for (int i = 0; i < statements->length(); i++) {
    1045             :     // Allocate an outer register allocations scope for the statement.
    1046             :     RegisterAllocationScope allocation_scope(this);
    1047    37307574 :     Statement* stmt = statements->at(i);
    1048    15966998 :     Visit(stmt);
    1049    15967002 :     if (stmt->IsJump()) break;
    1050    13966419 :   }
    1051     7374167 : }
    1052             : 
    1053    18458304 : void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
    1054             :   builder()->SetStatementPosition(stmt);
    1055     9229152 :   VisitForEffect(stmt->expression());
    1056     9229162 : }
    1057             : 
    1058           0 : void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
    1059           0 : }
    1060             : 
    1061    10901758 : void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
    1062             :   builder()->SetStatementPosition(stmt);
    1063     1146399 :   if (stmt->condition()->ToBooleanIsTrue()) {
    1064             :     // Generate then block unconditionally as always true.
    1065         275 :     Visit(stmt->then_statement());
    1066     1146124 :   } else if (stmt->condition()->ToBooleanIsFalse()) {
    1067             :     // Generate else block unconditionally if it exists.
    1068        8212 :     if (stmt->HasElseStatement()) {
    1069        6439 :       Visit(stmt->else_statement());
    1070             :     }
    1071             :   } else {
    1072             :     // TODO(oth): If then statement is BreakStatement or
    1073             :     // ContinueStatement we can reduce number of generated
    1074             :     // jump/jump_ifs here. See BasicLoops test.
    1075             :     BytecodeLabel end_label;
    1076             :     BytecodeLabels then_labels(zone()), else_labels(zone());
    1077             :     VisitForTest(stmt->condition(), &then_labels, &else_labels,
    1078     1137912 :                  TestFallthrough::kThen);
    1079             : 
    1080     1137912 :     then_labels.Bind(builder());
    1081     1137912 :     Visit(stmt->then_statement());
    1082             : 
    1083     1137912 :     if (stmt->HasElseStatement()) {
    1084      314326 :       builder()->Jump(&end_label);
    1085      314326 :       else_labels.Bind(builder());
    1086      314326 :       Visit(stmt->else_statement());
    1087             :     } else {
    1088      823586 :       else_labels.Bind(builder());
    1089             :     }
    1090     1137910 :     builder()->Bind(&end_label);
    1091             :   }
    1092     1146399 : }
    1093             : 
    1094        3476 : void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
    1095        3476 :     SloppyBlockFunctionStatement* stmt) {
    1096        3476 :   Visit(stmt->statement());
    1097        3476 : }
    1098             : 
    1099       23772 : void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
    1100             :   builder()->SetStatementPosition(stmt);
    1101             :   execution_control()->Continue(stmt->target());
    1102       11886 : }
    1103             : 
    1104      152678 : void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
    1105             :   builder()->SetStatementPosition(stmt);
    1106             :   execution_control()->Break(stmt->target());
    1107       76339 : }
    1108             : 
    1109     6284643 : void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    1110             :   builder()->SetStatementPosition(stmt);
    1111     2094878 :   VisitForAccumulatorValue(stmt->expression());
    1112     2094887 :   if (stmt->is_async_return()) {
    1113             :     execution_control()->AsyncReturnAccumulator();
    1114             :   } else {
    1115             :     execution_control()->ReturnAccumulator();
    1116             :   }
    1117     2094887 : }
    1118             : 
    1119       16212 : void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
    1120             :   builder()->SetStatementPosition(stmt);
    1121        4053 :   VisitForAccumulatorValue(stmt->expression());
    1122        4053 :   BuildNewLocalWithContext(stmt->scope());
    1123        4053 :   VisitInScope(stmt->statement(), stmt->scope());
    1124        4053 : }
    1125             : 
    1126      182217 : void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
    1127             :   // We need this scope because we visit for register values. We have to
    1128             :   // maintain a execution result scope where registers can be allocated.
    1129             :   ZoneList<CaseClause*>* clauses = stmt->cases();
    1130      302576 :   SwitchBuilder switch_builder(builder(), clauses->length());
    1131             :   ControlScopeForBreakable scope(this, stmt, &switch_builder);
    1132             :   int default_index = -1;
    1133             : 
    1134             :   builder()->SetStatementPosition(stmt);
    1135             : 
    1136             :   // Keep the switch value in a register until a case matches.
    1137       18873 :   Register tag = VisitForRegisterValue(stmt->tag());
    1138             : 
    1139             :   // Iterate over all cases and create nodes for label comparison.
    1140      264830 :   for (int i = 0; i < clauses->length(); i++) {
    1141      113542 :     CaseClause* clause = clauses->at(i);
    1142             : 
    1143             :     // The default is not a test, remember index.
    1144      113542 :     if (clause->is_default()) {
    1145             :       default_index = i;
    1146             :       continue;
    1147             :     }
    1148             : 
    1149             :     // Perform label comparison as if via '===' with tag.
    1150      106725 :     VisitForAccumulatorValue(clause->label());
    1151             :     builder()->CompareOperation(
    1152             :         Token::Value::EQ_STRICT, tag,
    1153      106725 :         feedback_index(clause->CompareOperationFeedbackSlot()));
    1154      106725 :     switch_builder.Case(ToBooleanMode::kAlreadyBoolean, i);
    1155             :   }
    1156             : 
    1157       18873 :   if (default_index >= 0) {
    1158             :     // Emit default jump if there is a default case.
    1159        6817 :     switch_builder.DefaultAt(default_index);
    1160             :   } else {
    1161             :     // Otherwise if we have reached here none of the cases matched, so jump to
    1162             :     // the end.
    1163             :     switch_builder.Break();
    1164             :   }
    1165             : 
    1166             :   // Iterate over all cases and create the case bodies.
    1167      245957 :   for (int i = 0; i < clauses->length(); i++) {
    1168      227084 :     CaseClause* clause = clauses->at(i);
    1169      113542 :     switch_builder.SetCaseTarget(i);
    1170      113542 :     VisitStatements(clause->statements());
    1171             :   }
    1172       37746 :   switch_builder.BindBreakTarget();
    1173       18873 : }
    1174             : 
    1175           0 : void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
    1176             :   // Handled entirely in VisitSwitchStatement.
    1177           0 :   UNREACHABLE();
    1178             : }
    1179             : 
    1180      386088 : void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
    1181      193044 :                                            LoopBuilder* loop_builder) {
    1182             :   ControlScopeForIteration execution_control(this, stmt, loop_builder);
    1183      386088 :   builder()->StackCheck(stmt->position());
    1184      193044 :   Visit(stmt->body());
    1185      193044 :   loop_builder->BindContinueTarget();
    1186      193044 : }
    1187             : 
    1188       10568 : void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
    1189             :   LoopBuilder loop_builder(builder());
    1190        2191 :   if (stmt->cond()->ToBooleanIsFalse()) {
    1191         304 :     VisitIterationBody(stmt, &loop_builder);
    1192        1887 :   } else if (stmt->cond()->ToBooleanIsTrue()) {
    1193         454 :     VisitIterationHeader(stmt, &loop_builder);
    1194         454 :     VisitIterationBody(stmt, &loop_builder);
    1195         454 :     loop_builder.JumpToHeader(loop_depth_);
    1196             :   } else {
    1197        1433 :     VisitIterationHeader(stmt, &loop_builder);
    1198        1433 :     VisitIterationBody(stmt, &loop_builder);
    1199             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1200             :     BytecodeLabels loop_backbranch(zone());
    1201             :     VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
    1202        1433 :                  TestFallthrough::kThen);
    1203        1433 :     loop_backbranch.Bind(builder());
    1204        1433 :     loop_builder.JumpToHeader(loop_depth_);
    1205             :   }
    1206        2191 :   loop_builder.EndLoop();
    1207        2191 : }
    1208             : 
    1209       86754 : void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
    1210       17304 :   if (stmt->cond()->ToBooleanIsFalse()) {
    1211             :     // If the condition is false there is no need to generate the loop.
    1212         105 :     return;
    1213             :   }
    1214             : 
    1215             :   LoopBuilder loop_builder(builder());
    1216       17199 :   VisitIterationHeader(stmt, &loop_builder);
    1217       17199 :   if (!stmt->cond()->ToBooleanIsTrue()) {
    1218             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1219             :     BytecodeLabels loop_body(zone());
    1220             :     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
    1221       11684 :                  TestFallthrough::kThen);
    1222       11684 :     loop_body.Bind(builder());
    1223             :   }
    1224       17199 :   VisitIterationBody(stmt, &loop_builder);
    1225       17199 :   loop_builder.JumpToHeader(loop_depth_);
    1226       17199 :   loop_builder.EndLoop();
    1227             : }
    1228             : 
    1229     1177186 : void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
    1230      150610 :   if (stmt->init() != nullptr) {
    1231       99176 :     Visit(stmt->init());
    1232             :   }
    1233      150610 :   if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
    1234             :     // If the condition is known to be false there is no need to generate
    1235             :     // body, next or condition blocks. Init block should be generated.
    1236       14543 :     return;
    1237             :   }
    1238             : 
    1239             :   LoopBuilder loop_builder(builder());
    1240      136067 :   VisitIterationHeader(stmt, &loop_builder);
    1241      136067 :   if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
    1242             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1243             :     BytecodeLabels loop_body(zone());
    1244             :     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
    1245      118604 :                  TestFallthrough::kThen);
    1246      118604 :     loop_body.Bind(builder());
    1247             :   }
    1248      136067 :   VisitIterationBody(stmt, &loop_builder);
    1249      136067 :   if (stmt->next() != nullptr) {
    1250             :     builder()->SetStatementPosition(stmt->next());
    1251      111953 :     Visit(stmt->next());
    1252             :   }
    1253      136067 :   loop_builder.JumpToHeader(loop_depth_);
    1254      136067 :   loop_builder.EndLoop();
    1255             : }
    1256             : 
    1257        5764 : void BytecodeGenerator::VisitForInAssignment(Expression* expr,
    1258         462 :                                              FeedbackSlot slot) {
    1259             :   DCHECK(expr->IsValidReferenceExpression());
    1260             : 
    1261             :   // Evaluate assignment starting with the value to be stored in the
    1262             :   // accumulator.
    1263        6084 :   Property* property = expr->AsProperty();
    1264        5764 :   LhsKind assign_type = Property::GetAssignType(property);
    1265        5764 :   switch (assign_type) {
    1266             :     case VARIABLE: {
    1267       11208 :       VariableProxy* proxy = expr->AsVariableProxy();
    1268             :       BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot,
    1269        5604 :                               proxy->hole_check_mode());
    1270        5604 :       break;
    1271             :     }
    1272             :     case NAMED_PROPERTY: {
    1273             :       RegisterAllocationScope register_scope(this);
    1274          25 :       Register value = register_allocator()->NewRegister();
    1275          25 :       builder()->StoreAccumulatorInRegister(value);
    1276          25 :       Register object = VisitForRegisterValue(property->obj());
    1277             :       const AstRawString* name =
    1278          50 :           property->key()->AsLiteral()->AsRawPropertyName();
    1279          25 :       builder()->LoadAccumulatorWithRegister(value);
    1280             :       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    1281          25 :                                     language_mode());
    1282          25 :       break;
    1283             :     }
    1284             :     case KEYED_PROPERTY: {
    1285             :       RegisterAllocationScope register_scope(this);
    1286         117 :       Register value = register_allocator()->NewRegister();
    1287         117 :       builder()->StoreAccumulatorInRegister(value);
    1288         117 :       Register object = VisitForRegisterValue(property->obj());
    1289         117 :       Register key = VisitForRegisterValue(property->key());
    1290         117 :       builder()->LoadAccumulatorWithRegister(value);
    1291             :       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    1292         117 :                                     language_mode());
    1293         117 :       break;
    1294             :     }
    1295             :     case NAMED_SUPER_PROPERTY: {
    1296             :       RegisterAllocationScope register_scope(this);
    1297           6 :       RegisterList args = register_allocator()->NewRegisterList(4);
    1298           6 :       builder()->StoreAccumulatorInRegister(args[3]);
    1299          12 :       SuperPropertyReference* super_property =
    1300           6 :           property->obj()->AsSuperPropertyReference();
    1301           6 :       VisitForRegisterValue(super_property->this_var(), args[0]);
    1302           6 :       VisitForRegisterValue(super_property->home_object(), args[1]);
    1303             :       builder()
    1304          18 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    1305           6 :           .StoreAccumulatorInRegister(args[2])
    1306           6 :           .CallRuntime(StoreToSuperRuntimeId(), args);
    1307           6 :       break;
    1308             :     }
    1309             :     case KEYED_SUPER_PROPERTY: {
    1310             :       RegisterAllocationScope register_scope(this);
    1311          12 :       RegisterList args = register_allocator()->NewRegisterList(4);
    1312          12 :       builder()->StoreAccumulatorInRegister(args[3]);
    1313          24 :       SuperPropertyReference* super_property =
    1314          12 :           property->obj()->AsSuperPropertyReference();
    1315          12 :       VisitForRegisterValue(super_property->this_var(), args[0]);
    1316          12 :       VisitForRegisterValue(super_property->home_object(), args[1]);
    1317          12 :       VisitForRegisterValue(property->key(), args[2]);
    1318          12 :       builder()->CallRuntime(StoreKeyedToSuperRuntimeId(), args);
    1319          12 :       break;
    1320             :     }
    1321             :   }
    1322        5764 : }
    1323             : 
    1324       98101 : void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
    1325       11641 :   if (stmt->subject()->IsNullLiteral() ||
    1326        5800 :       stmt->subject()->IsUndefinedLiteral()) {
    1327             :     // ForIn generates lots of code, skip if it wouldn't produce any effects.
    1328          77 :     return;
    1329             :   }
    1330             : 
    1331             :   LoopBuilder loop_builder(builder());
    1332             :   BytecodeLabel subject_null_label, subject_undefined_label;
    1333             : 
    1334             :   // Prepare the state for executing ForIn.
    1335             :   builder()->SetExpressionAsStatementPosition(stmt->subject());
    1336        5764 :   VisitForAccumulatorValue(stmt->subject());
    1337        5764 :   builder()->JumpIfUndefined(&subject_undefined_label);
    1338        5764 :   builder()->JumpIfNull(&subject_null_label);
    1339        5764 :   Register receiver = register_allocator()->NewRegister();
    1340        5764 :   builder()->ConvertAccumulatorToObject(receiver);
    1341             : 
    1342             :   // Used as kRegTriple and kRegPair in ForInPrepare and ForInNext.
    1343        5764 :   RegisterList triple = register_allocator()->NewRegisterList(3);
    1344        5764 :   Register cache_length = triple[2];
    1345        5764 :   builder()->ForInPrepare(receiver, triple);
    1346             : 
    1347             :   // Set up loop counter
    1348        5764 :   Register index = register_allocator()->NewRegister();
    1349        5764 :   builder()->LoadLiteral(Smi::kZero);
    1350        5764 :   builder()->StoreAccumulatorInRegister(index);
    1351             : 
    1352             :   // The loop
    1353        5764 :   VisitIterationHeader(stmt, &loop_builder);
    1354             :   builder()->SetExpressionAsStatementPosition(stmt->each());
    1355        5764 :   builder()->ForInContinue(index, cache_length);
    1356             :   loop_builder.BreakIfFalse(ToBooleanMode::kAlreadyBoolean);
    1357             :   FeedbackSlot slot = stmt->ForInFeedbackSlot();
    1358             :   builder()->ForInNext(receiver, index, triple.Truncate(2),
    1359        5764 :                        feedback_index(slot));
    1360             :   loop_builder.ContinueIfUndefined();
    1361        5764 :   VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
    1362        5764 :   VisitIterationBody(stmt, &loop_builder);
    1363        5764 :   builder()->ForInStep(index);
    1364        5764 :   builder()->StoreAccumulatorInRegister(index);
    1365        5764 :   loop_builder.JumpToHeader(loop_depth_);
    1366        5764 :   loop_builder.EndLoop();
    1367        5764 :   builder()->Bind(&subject_null_label);
    1368        5764 :   builder()->Bind(&subject_undefined_label);
    1369             : }
    1370             : 
    1371      159115 : void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
    1372             :   LoopBuilder loop_builder(builder());
    1373             : 
    1374             :   builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
    1375       31823 :   VisitForEffect(stmt->assign_iterator());
    1376             : 
    1377       31823 :   VisitIterationHeader(stmt, &loop_builder);
    1378             :   builder()->SetExpressionAsStatementPosition(stmt->next_result());
    1379       31823 :   VisitForEffect(stmt->next_result());
    1380       31823 :   TypeHint type_hint = VisitForAccumulatorValue(stmt->result_done());
    1381             :   loop_builder.BreakIfTrue(ToBooleanModeFromTypeHint(type_hint));
    1382             : 
    1383       31823 :   VisitForEffect(stmt->assign_each());
    1384       31823 :   VisitIterationBody(stmt, &loop_builder);
    1385       31823 :   loop_builder.JumpToHeader(loop_depth_);
    1386       31823 :   loop_builder.EndLoop();
    1387       31823 : }
    1388             : 
    1389     1122335 : void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
    1390      256532 :   TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction());
    1391             : 
    1392             :   // Preserve the context in a dedicated register, so that it can be restored
    1393             :   // when the handler is entered by the stack-unwinding machinery.
    1394             :   // TODO(mstarzinger): Be smarter about register allocation.
    1395      128266 :   Register context = register_allocator()->NewRegister();
    1396      256532 :   builder()->MoveRegister(Register::current_context(), context);
    1397             : 
    1398             :   // Evaluate the try-block inside a control scope. This simulates a handler
    1399             :   // that is intercepting 'throw' control commands.
    1400      128266 :   try_control_builder.BeginTry(context);
    1401             :   {
    1402             :     ControlScopeForTryCatch scope(this, &try_control_builder);
    1403      128266 :     Visit(stmt->try_block());
    1404             :   }
    1405      128266 :   try_control_builder.EndTry();
    1406             : 
    1407             :   // Create a catch scope that binds the exception.
    1408      128266 :   BuildNewLocalCatchContext(stmt->scope());
    1409      128266 :   builder()->StoreAccumulatorInRegister(context);
    1410             : 
    1411             :   // If requested, clear message object as we enter the catch block.
    1412      128266 :   if (stmt->clear_pending_message()) {
    1413       96207 :     builder()->LoadTheHole().SetPendingMessage();
    1414             :   }
    1415             : 
    1416             :   // Load the catch context into the accumulator.
    1417      128266 :   builder()->LoadAccumulatorWithRegister(context);
    1418             : 
    1419             :   // Evaluate the catch-block.
    1420      128266 :   VisitInScope(stmt->catch_block(), stmt->scope());
    1421      128266 :   try_control_builder.EndCatch();
    1422      128266 : }
    1423             : 
    1424      289596 : void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
    1425       96532 :   TryFinallyBuilder try_control_builder(builder(), stmt->catch_prediction());
    1426             : 
    1427             :   // We keep a record of all paths that enter the finally-block to be able to
    1428             :   // dispatch to the correct continuation point after the statements in the
    1429             :   // finally-block have been evaluated.
    1430             :   //
    1431             :   // The try-finally construct can enter the finally-block in three ways:
    1432             :   // 1. By exiting the try-block normally, falling through at the end.
    1433             :   // 2. By exiting the try-block with a function-local control flow transfer
    1434             :   //    (i.e. through break/continue/return statements).
    1435             :   // 3. By exiting the try-block with a thrown exception.
    1436             :   //
    1437             :   // The result register semantics depend on how the block was entered:
    1438             :   //  - ReturnStatement: It represents the return value being returned.
    1439             :   //  - ThrowStatement: It represents the exception being thrown.
    1440             :   //  - BreakStatement/ContinueStatement: Undefined and not used.
    1441             :   //  - Falling through into finally-block: Undefined and not used.
    1442       48266 :   Register token = register_allocator()->NewRegister();
    1443       48266 :   Register result = register_allocator()->NewRegister();
    1444             :   ControlScope::DeferredCommands commands(this, token, result);
    1445             : 
    1446             :   // Preserve the context in a dedicated register, so that it can be restored
    1447             :   // when the handler is entered by the stack-unwinding machinery.
    1448             :   // TODO(mstarzinger): Be smarter about register allocation.
    1449       48266 :   Register context = register_allocator()->NewRegister();
    1450       96532 :   builder()->MoveRegister(Register::current_context(), context);
    1451             : 
    1452             :   // Evaluate the try-block inside a control scope. This simulates a handler
    1453             :   // that is intercepting all control commands.
    1454       48266 :   try_control_builder.BeginTry(context);
    1455             :   {
    1456             :     ControlScopeForTryFinally scope(this, &try_control_builder, &commands);
    1457       48266 :     Visit(stmt->try_block());
    1458             :   }
    1459       48266 :   try_control_builder.EndTry();
    1460             : 
    1461             :   // Record fall-through and exception cases.
    1462       48266 :   commands.RecordFallThroughPath();
    1463       48266 :   try_control_builder.LeaveTry();
    1464       48266 :   try_control_builder.BeginHandler();
    1465             :   commands.RecordHandlerReThrowPath();
    1466             : 
    1467             :   // Pending message object is saved on entry.
    1468       48266 :   try_control_builder.BeginFinally();
    1469       48266 :   Register message = context;  // Reuse register.
    1470             : 
    1471             :   // Clear message object as we enter the finally block.
    1472       48266 :   builder()->LoadTheHole().SetPendingMessage().StoreAccumulatorInRegister(
    1473       48266 :       message);
    1474             : 
    1475             :   // Evaluate the finally-block.
    1476       48266 :   Visit(stmt->finally_block());
    1477       48266 :   try_control_builder.EndFinally();
    1478             : 
    1479             :   // Pending message object is restored on exit.
    1480       48266 :   builder()->LoadAccumulatorWithRegister(message).SetPendingMessage();
    1481             : 
    1482             :   // Dynamic dispatch after the finally-block.
    1483       48266 :   commands.ApplyDeferredCommands();
    1484       48266 : }
    1485             : 
    1486        9511 : void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
    1487             :   builder()->SetStatementPosition(stmt);
    1488        9511 :   builder()->Debugger();
    1489           0 : }
    1490             : 
    1491    10303303 : void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
    1492             :   uint8_t flags = CreateClosureFlags::Encode(
    1493    10303296 :       expr->pretenure(), closure_scope()->is_function_scope());
    1494     3434437 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    1495             :   int slot_index = feedback_index(expr->LiteralFeedbackSlot());
    1496     6868868 :   builder()->CreateClosure(entry, slot_index, flags);
    1497     6868874 :   function_literals_.push_back(std::make_pair(expr, entry));
    1498     3434437 : }
    1499             : 
    1500      333576 : void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
    1501       41550 :   Register constructor = VisitForRegisterValue(expr->constructor());
    1502             :   {
    1503             :     RegisterAllocationScope register_scope(this);
    1504       41550 :     RegisterList args = register_allocator()->NewRegisterList(4);
    1505       41550 :     VisitForAccumulatorValueOrTheHole(expr->extends());
    1506             :     builder()
    1507       41550 :         ->StoreAccumulatorInRegister(args[0])
    1508       41550 :         .MoveRegister(constructor, args[1])
    1509       41550 :         .LoadLiteral(Smi::FromInt(expr->start_position()))
    1510       41550 :         .StoreAccumulatorInRegister(args[2])
    1511       41550 :         .LoadLiteral(Smi::FromInt(expr->end_position()))
    1512       41550 :         .StoreAccumulatorInRegister(args[3])
    1513       41550 :         .CallRuntime(Runtime::kDefineClass, args);
    1514             :   }
    1515       41550 :   Register prototype = register_allocator()->NewRegister();
    1516       41550 :   builder()->StoreAccumulatorInRegister(prototype);
    1517             : 
    1518       41550 :   if (FunctionLiteral::NeedsHomeObject(expr->constructor())) {
    1519             :     // Prototype is already in the accumulator.
    1520             :     builder()->StoreHomeObjectProperty(
    1521        1176 :         constructor, feedback_index(expr->HomeObjectSlot()), language_mode());
    1522             :   }
    1523             : 
    1524       41550 :   VisitClassLiteralProperties(expr, constructor, prototype);
    1525       41550 :   BuildClassLiteralNameProperty(expr, constructor);
    1526       41550 :   builder()->CallRuntime(Runtime::kToFastProperties, constructor);
    1527             :   // Assign to class variable.
    1528       41550 :   if (expr->class_variable_proxy() != nullptr) {
    1529       40034 :     VariableProxy* proxy = expr->class_variable_proxy();
    1530             :     FeedbackSlot slot =
    1531       40034 :         expr->NeedsProxySlot() ? expr->ProxySlot() : FeedbackSlot::Invalid();
    1532             :     BuildVariableAssignment(proxy->var(), Token::INIT, slot,
    1533       40034 :                             HoleCheckMode::kElided);
    1534             :   }
    1535       41550 : }
    1536             : 
    1537      385866 : void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
    1538             :                                                     Register constructor,
    1539      353165 :                                                     Register prototype) {
    1540             :   RegisterAllocationScope register_scope(this);
    1541       41550 :   RegisterList args = register_allocator()->NewRegisterList(4);
    1542      166200 :   Register receiver = args[0], key = args[1], value = args[2], attr = args[3];
    1543             : 
    1544             :   bool attr_assigned = false;
    1545             :   Register old_receiver = Register::invalid_value();
    1546             : 
    1547             :   // Create nodes to store method values into the literal.
    1548      688632 :   for (int i = 0; i < expr->properties()->length(); i++) {
    1549      908298 :     ClassLiteral::Property* property = expr->properties()->at(i);
    1550             : 
    1551             :     // Set-up receiver.
    1552      302766 :     Register new_receiver = property->is_static() ? constructor : prototype;
    1553      302766 :     if (new_receiver != old_receiver) {
    1554       23403 :       builder()->MoveRegister(new_receiver, receiver);
    1555             :       old_receiver = new_receiver;
    1556             :     }
    1557             : 
    1558      302766 :     BuildLoadPropertyKey(property, key);
    1559      605532 :     if (property->is_static() && property->is_computed_name()) {
    1560             :       // The static prototype property is read only. We handle the non computed
    1561             :       // property name case in the parser. Since this is the only case where we
    1562             :       // need to check for an own read only property we special case this so we
    1563             :       // do not need to do this for every property.
    1564             :       BytecodeLabel done;
    1565             :       builder()
    1566        3944 :           ->LoadLiteral(ast_string_constants()->prototype_string())
    1567        1972 :           .CompareOperation(Token::Value::EQ_STRICT, key)
    1568        1972 :           .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done)
    1569        1972 :           .CallRuntime(Runtime::kThrowStaticPrototypeError)
    1570        1972 :           .Bind(&done);
    1571             :     }
    1572             : 
    1573      302766 :     VisitForRegisterValue(property->value(), value);
    1574      302766 :     VisitSetHomeObject(value, receiver, property);
    1575             : 
    1576      302766 :     if (!attr_assigned) {
    1577             :       builder()
    1578       23052 :           ->LoadLiteral(Smi::FromInt(DONT_ENUM))
    1579       23052 :           .StoreAccumulatorInRegister(attr);
    1580             :       attr_assigned = true;
    1581             :     }
    1582             : 
    1583      302766 :     switch (property->kind()) {
    1584             :       case ClassLiteral::Property::METHOD: {
    1585             :         DataPropertyInLiteralFlags flags = DataPropertyInLiteralFlag::kDontEnum;
    1586      290393 :         if (property->NeedsSetFunctionName()) {
    1587             :           flags |= DataPropertyInLiteralFlag::kSetFunctionName;
    1588             :         }
    1589             : 
    1590      290393 :         FeedbackSlot slot = property->GetStoreDataPropertySlot();
    1591             :         DCHECK(!slot.IsInvalid());
    1592             : 
    1593             :         builder()
    1594      290393 :             ->LoadAccumulatorWithRegister(value)
    1595             :             .StoreDataPropertyInLiteral(receiver, key, flags,
    1596      290393 :                                         feedback_index(slot));
    1597             :         break;
    1598             :       }
    1599             :       case ClassLiteral::Property::GETTER: {
    1600        8258 :         builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked, args);
    1601        8258 :         break;
    1602             :       }
    1603             :       case ClassLiteral::Property::SETTER: {
    1604        4115 :         builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, args);
    1605        4115 :         break;
    1606             :       }
    1607             :       case ClassLiteral::Property::FIELD: {
    1608           0 :         UNREACHABLE();
    1609             :         break;
    1610             :       }
    1611             :     }
    1612       41550 :   }
    1613       41550 : }
    1614             : 
    1615       82996 : void BytecodeGenerator::BuildClassLiteralNameProperty(ClassLiteral* expr,
    1616       40400 :                                                       Register literal) {
    1617       82996 :   if (!expr->has_name_static_property() &&
    1618       41446 :       !expr->constructor()->raw_name()->IsEmpty()) {
    1619             :     Runtime::FunctionId runtime_id =
    1620             :         expr->has_static_computed_names()
    1621             :             ? Runtime::kInstallClassNameAccessorWithCheck
    1622       40400 :             : Runtime::kInstallClassNameAccessor;
    1623       40400 :     builder()->CallRuntime(runtime_id, literal);
    1624             :   }
    1625       41550 : }
    1626             : 
    1627        2483 : void BytecodeGenerator::VisitNativeFunctionLiteral(
    1628        4966 :     NativeFunctionLiteral* expr) {
    1629        2483 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    1630             :   int slot_index = feedback_index(expr->LiteralFeedbackSlot());
    1631        2483 :   builder()->CreateClosure(entry, slot_index, NOT_TENURED);
    1632        4966 :   native_function_literals_.push_back(std::make_pair(expr, entry));
    1633        2483 : }
    1634             : 
    1635      166472 : void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
    1636       83236 :   VisitBlock(expr->block());
    1637       83236 :   VisitVariableProxy(expr->result());
    1638       83236 : }
    1639             : 
    1640      602933 : void BytecodeGenerator::VisitConditional(Conditional* expr) {
    1641       60532 :   if (expr->condition()->ToBooleanIsTrue()) {
    1642             :     // Generate then block unconditionally as always true.
    1643         224 :     VisitForAccumulatorValue(expr->then_expression());
    1644       60308 :   } else if (expr->condition()->ToBooleanIsFalse()) {
    1645             :     // Generate else block unconditionally if it exists.
    1646          85 :     VisitForAccumulatorValue(expr->else_expression());
    1647             :   } else {
    1648             :     BytecodeLabel end_label;
    1649             :     BytecodeLabels then_labels(zone()), else_labels(zone());
    1650             : 
    1651             :     VisitForTest(expr->condition(), &then_labels, &else_labels,
    1652       60223 :                  TestFallthrough::kThen);
    1653             : 
    1654       60223 :     then_labels.Bind(builder());
    1655       60223 :     VisitForAccumulatorValue(expr->then_expression());
    1656       60223 :     builder()->Jump(&end_label);
    1657             : 
    1658       60223 :     else_labels.Bind(builder());
    1659       60223 :     VisitForAccumulatorValue(expr->else_expression());
    1660       60223 :     builder()->Bind(&end_label);
    1661             :   }
    1662       60532 : }
    1663             : 
    1664    17904394 : void BytecodeGenerator::VisitLiteral(Literal* expr) {
    1665     9447359 :   if (!execution_result()->IsEffect()) {
    1666     8147633 :     const AstValue* raw_value = expr->raw_value();
    1667     8147633 :     builder()->LoadLiteral(raw_value);
    1668    16176739 :     if (raw_value->IsTrue() || raw_value->IsFalse()) {
    1669             :       execution_result()->SetResultIsBoolean();
    1670             :     }
    1671             :   }
    1672     9447359 : }
    1673             : 
    1674      105716 : void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
    1675             :   // Materialize a regular expression literal.
    1676             :   builder()->CreateRegExpLiteral(
    1677       52858 :       expr->raw_pattern(), feedback_index(expr->literal_slot()), expr->flags());
    1678           0 : }
    1679             : 
    1680     2147032 : void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
    1681             :   // Deep-copy the literal boilerplate.
    1682             :   uint8_t flags = CreateObjectLiteralFlags::Encode(
    1683      346962 :       expr->IsFastCloningSupported(),
    1684             :       ConstructorBuiltins::FastCloneShallowObjectPropertiesCount(
    1685             :           expr->properties_count()),
    1686     2970655 :       expr->ComputeFlags());
    1687             : 
    1688      346962 :   Register literal = register_allocator()->NewRegister();
    1689             :   size_t entry;
    1690             :   // If constant properties is an empty fixed array, use a cached empty fixed
    1691             :   // array to ensure it's only added to the constant pool once.
    1692      346962 :   if (expr->properties_count() == 0) {
    1693       50629 :     entry = builder()->EmptyFixedArrayConstantPoolEntry();
    1694             :   } else {
    1695      296333 :     entry = builder()->AllocateDeferredConstantPoolEntry();
    1696      592666 :     object_literals_.push_back(std::make_pair(expr, entry));
    1697             :   }
    1698             :   builder()->CreateObjectLiteral(entry, feedback_index(expr->literal_slot()),
    1699      693924 :                                  flags, literal);
    1700             : 
    1701             :   // Store computed values into the literal.
    1702             :   int property_index = 0;
    1703             :   AccessorTable accessor_table(zone());
    1704     2810812 :   for (; property_index < expr->properties()->length(); property_index++) {
    1705     1612214 :     ObjectLiteral::Property* property = expr->properties()->at(property_index);
    1706     2334801 :     if (property->is_computed_name()) break;
    1707     2085370 :     if (property->IsCompileTimeValue()) continue;
    1708             : 
    1709             :     RegisterAllocationScope inner_register_scope(this);
    1710      726860 :     Literal* key = property->key()->AsLiteral();
    1711      378480 :     switch (property->kind()) {
    1712             :       case ObjectLiteral::Property::SPREAD:
    1713             :       case ObjectLiteral::Property::CONSTANT:
    1714           0 :         UNREACHABLE();
    1715             :       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
    1716             :         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
    1717             :       // Fall through.
    1718             :       case ObjectLiteral::Property::COMPUTED: {
    1719             :         // It is safe to use [[Put]] here because the boilerplate already
    1720             :         // contains computed properties with an uninitialized value.
    1721      348995 :         if (key->IsStringLiteral()) {
    1722             :           DCHECK(key->IsPropertyName());
    1723      348512 :           if (property->emit_store()) {
    1724      348380 :             VisitForAccumulatorValue(property->value());
    1725      348380 :             if (FunctionLiteral::NeedsHomeObject(property->value())) {
    1726             :               RegisterAllocationScope register_scope(this);
    1727         395 :               Register value = register_allocator()->NewRegister();
    1728         395 :               builder()->StoreAccumulatorInRegister(value);
    1729             :               builder()->StoreNamedOwnProperty(
    1730             :                   literal, key->AsRawPropertyName(),
    1731         790 :                   feedback_index(property->GetSlot(0)));
    1732         395 :               VisitSetHomeObject(value, literal, property, 1);
    1733             :             } else {
    1734             :               builder()->StoreNamedOwnProperty(
    1735             :                   literal, key->AsRawPropertyName(),
    1736      695970 :                   feedback_index(property->GetSlot(0)));
    1737             :             }
    1738             :           } else {
    1739         132 :             VisitForEffect(property->value());
    1740             :           }
    1741             :         } else {
    1742         483 :           RegisterList args = register_allocator()->NewRegisterList(4);
    1743             : 
    1744         483 :           builder()->MoveRegister(literal, args[0]);
    1745         483 :           VisitForRegisterValue(property->key(), args[1]);
    1746         483 :           VisitForRegisterValue(property->value(), args[2]);
    1747         483 :           if (property->emit_store()) {
    1748             :             builder()
    1749         454 :                 ->LoadLiteral(Smi::FromInt(SLOPPY))
    1750         454 :                 .StoreAccumulatorInRegister(args[3])
    1751         454 :                 .CallRuntime(Runtime::kSetProperty, args);
    1752         454 :             Register value = args[2];
    1753         454 :             VisitSetHomeObject(value, literal, property);
    1754             :           }
    1755             :         }
    1756             :         break;
    1757             :       }
    1758             :       case ObjectLiteral::Property::PROTOTYPE: {
    1759             :         DCHECK(property->emit_store());
    1760       24729 :         RegisterList args = register_allocator()->NewRegisterList(2);
    1761       24729 :         builder()->MoveRegister(literal, args[0]);
    1762       24729 :         VisitForRegisterValue(property->value(), args[1]);
    1763       24729 :         builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
    1764             :         break;
    1765             :       }
    1766             :       case ObjectLiteral::Property::GETTER:
    1767        2728 :         if (property->emit_store()) {
    1768        2663 :           accessor_table.lookup(key)->second->getter = property;
    1769             :         }
    1770             :         break;
    1771             :       case ObjectLiteral::Property::SETTER:
    1772        2028 :         if (property->emit_store()) {
    1773        1973 :           accessor_table.lookup(key)->second->setter = property;
    1774             :         }
    1775             :         break;
    1776             :     }
    1777      378480 :   }
    1778             : 
    1779             :   // Define accessors, using only a single call to the runtime for each pair of
    1780             :   // corresponding getters and setters.
    1781      698035 :   for (AccessorTable::Iterator it = accessor_table.begin();
    1782             :        it != accessor_table.end(); ++it) {
    1783             :     RegisterAllocationScope inner_register_scope(this);
    1784        4111 :     RegisterList args = register_allocator()->NewRegisterList(5);
    1785        4111 :     builder()->MoveRegister(literal, args[0]);
    1786        4111 :     VisitForRegisterValue(it->first, args[1]);
    1787        4111 :     VisitObjectLiteralAccessor(literal, it->second->getter, args[2]);
    1788        4111 :     VisitObjectLiteralAccessor(literal, it->second->setter, args[3]);
    1789             :     builder()
    1790        4111 :         ->LoadLiteral(Smi::FromInt(NONE))
    1791        4111 :         .StoreAccumulatorInRegister(args[4])
    1792        4111 :         .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, args);
    1793        4111 :   }
    1794             : 
    1795             :   // Object literals have two parts. The "static" part on the left contains no
    1796             :   // computed property names, and so we can compute its map ahead of time; see
    1797             :   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
    1798             :   // with the first computed property name and continues with all properties to
    1799             :   // its right. All the code from above initializes the static component of the
    1800             :   // object literal, and arranges for the map of the result to reflect the
    1801             :   // static order in which the keys appear. For the dynamic properties, we
    1802             :   // compile them into a series of "SetOwnProperty" runtime calls. This will
    1803             :   // preserve insertion order.
    1804      354802 :   for (; property_index < expr->properties()->length(); property_index++) {
    1805        8151 :     ObjectLiteral::Property* property = expr->properties()->at(property_index);
    1806             :     RegisterAllocationScope inner_register_scope(this);
    1807             : 
    1808        3920 :     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
    1809             :       DCHECK(property->emit_store());
    1810          48 :       RegisterList args = register_allocator()->NewRegisterList(2);
    1811          48 :       builder()->MoveRegister(literal, args[0]);
    1812        3920 :       VisitForRegisterValue(property->value(), args[1]);
    1813          48 :       builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
    1814             :       continue;
    1815             :     }
    1816             : 
    1817        3872 :     switch (property->kind()) {
    1818             :       case ObjectLiteral::Property::CONSTANT:
    1819             :       case ObjectLiteral::Property::COMPUTED:
    1820             :       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
    1821        3321 :         Register key = register_allocator()->NewRegister();
    1822        3321 :         BuildLoadPropertyKey(property, key);
    1823        3321 :         Register value = VisitForRegisterValue(property->value());
    1824        3321 :         VisitSetHomeObject(value, literal, property);
    1825             : 
    1826             :         DataPropertyInLiteralFlags data_property_flags =
    1827             :             DataPropertyInLiteralFlag::kNoFlags;
    1828        3321 :         if (property->NeedsSetFunctionName()) {
    1829             :           data_property_flags |= DataPropertyInLiteralFlag::kSetFunctionName;
    1830             :         }
    1831             : 
    1832        3321 :         FeedbackSlot slot = property->GetStoreDataPropertySlot();
    1833             :         DCHECK(!slot.IsInvalid());
    1834             : 
    1835             :         builder()
    1836        3321 :             ->LoadAccumulatorWithRegister(value)
    1837             :             .StoreDataPropertyInLiteral(literal, key, data_property_flags,
    1838        3321 :                                         feedback_index(slot));
    1839             :         break;
    1840             :       }
    1841             :       case ObjectLiteral::Property::GETTER:
    1842             :       case ObjectLiteral::Property::SETTER: {
    1843         311 :         RegisterList args = register_allocator()->NewRegisterList(4);
    1844         311 :         builder()->MoveRegister(literal, args[0]);
    1845         311 :         BuildLoadPropertyKey(property, args[1]);
    1846         311 :         VisitForRegisterValue(property->value(), args[2]);
    1847         311 :         VisitSetHomeObject(args[2], literal, property);
    1848             :         builder()
    1849         311 :             ->LoadLiteral(Smi::FromInt(NONE))
    1850         311 :             .StoreAccumulatorInRegister(args[3]);
    1851             :         Runtime::FunctionId function_id =
    1852             :             property->kind() == ObjectLiteral::Property::GETTER
    1853             :                 ? Runtime::kDefineGetterPropertyUnchecked
    1854         311 :                 : Runtime::kDefineSetterPropertyUnchecked;
    1855         311 :         builder()->CallRuntime(function_id, args);
    1856             :         break;
    1857             :       }
    1858             :       case ObjectLiteral::Property::SPREAD: {
    1859         240 :         RegisterList args = register_allocator()->NewRegisterList(2);
    1860         240 :         builder()->MoveRegister(literal, args[0]);
    1861         240 :         VisitForRegisterValue(property->value(), args[1]);
    1862         240 :         builder()->CallRuntime(Runtime::kCopyDataProperties, args);
    1863             :         break;
    1864             :       }
    1865             :       case ObjectLiteral::Property::PROTOTYPE:
    1866           0 :         UNREACHABLE();  // Handled specially above.
    1867             :         break;
    1868             :     }
    1869        3872 :   }
    1870             : 
    1871      346962 :   builder()->LoadAccumulatorWithRegister(literal);
    1872      346962 : }
    1873             : 
    1874     1030458 : void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
    1875             :   // Deep-copy the literal boilerplate.
    1876             :   uint8_t flags = CreateArrayLiteralFlags::Encode(
    1877     7690792 :       expr->IsFastCloningSupported(), expr->ComputeFlags());
    1878             : 
    1879      151462 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    1880             :   builder()->CreateArrayLiteral(entry, feedback_index(expr->literal_slot()),
    1881      302924 :                                 flags);
    1882      302924 :   array_literals_.push_back(std::make_pair(expr, entry));
    1883             : 
    1884             :   Register index, literal;
    1885             : 
    1886             :   // Evaluate all the non-constant subexpressions and store them into the
    1887             :   // newly cloned array.
    1888             :   bool literal_in_accumulator = true;
    1889    15078660 :   for (int array_index = 0; array_index < expr->values()->length();
    1890             :        array_index++) {
    1891     7387868 :     Expression* subexpr = expr->values()->at(array_index);
    1892     7387868 :     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
    1893             :     DCHECK(!subexpr->IsSpread());
    1894             : 
    1895      238061 :     if (literal_in_accumulator) {
    1896       49975 :       index = register_allocator()->NewRegister();
    1897       49975 :       literal = register_allocator()->NewRegister();
    1898       49975 :       builder()->StoreAccumulatorInRegister(literal);
    1899             :       literal_in_accumulator = false;
    1900             :     }
    1901             : 
    1902             :     FeedbackSlot slot = expr->LiteralFeedbackSlot();
    1903             :     builder()
    1904      238061 :         ->LoadLiteral(Smi::FromInt(array_index))
    1905      238061 :         .StoreAccumulatorInRegister(index);
    1906      238061 :     VisitForAccumulatorValue(subexpr);
    1907             :     builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
    1908      238061 :                                   language_mode());
    1909             :   }
    1910             : 
    1911      151462 :   if (!literal_in_accumulator) {
    1912             :     // Restore literal array into accumulator.
    1913       49975 :     builder()->LoadAccumulatorWithRegister(literal);
    1914             :   }
    1915      151462 : }
    1916             : 
    1917    33441465 : void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
    1918             :   builder()->SetExpressionPosition(proxy);
    1919             :   BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
    1920    11147155 :                     proxy->hole_check_mode());
    1921    11147148 : }
    1922             : 
    1923    30197279 : void BytecodeGenerator::BuildVariableLoad(Variable* variable, FeedbackSlot slot,
    1924             :                                           HoleCheckMode hole_check_mode,
    1925    27324855 :                                           TypeofMode typeof_mode) {
    1926    12245705 :   switch (variable->location()) {
    1927             :     case VariableLocation::LOCAL: {
    1928     4068993 :       Register source(builder()->Local(variable->index()));
    1929             :       // We need to load the variable into the accumulator, even when in a
    1930             :       // VisitForRegisterScope, in order to avoid register aliasing if
    1931             :       // subsequent expressions assign to the same variable.
    1932     4068992 :       builder()->LoadAccumulatorWithRegister(source);
    1933     4068994 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    1934       15056 :         BuildThrowIfHole(variable);
    1935             :       }
    1936             :       break;
    1937             :     }
    1938             :     case VariableLocation::PARAMETER: {
    1939             :       Register source;
    1940     2971162 :       if (variable->IsReceiver()) {
    1941      744621 :         source = builder()->Receiver();
    1942             :       } else {
    1943     2226541 :         source = builder()->Parameter(variable->index());
    1944             :       }
    1945             :       // We need to load the variable into the accumulator, even when in a
    1946             :       // VisitForRegisterScope, in order to avoid register aliasing if
    1947             :       // subsequent expressions assign to the same variable.
    1948     2971162 :       builder()->LoadAccumulatorWithRegister(source);
    1949     2971162 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    1950       19843 :         BuildThrowIfHole(variable);
    1951             :       }
    1952             :       break;
    1953             :     }
    1954             :     case VariableLocation::UNALLOCATED: {
    1955             :       // The global identifier "undefined" is immutable. Everything
    1956             :       // else could be reassigned. For performance, we do a pointer comparison
    1957             :       // rather than checking if the raw_name is really "undefined".
    1958     1870080 :       if (variable->raw_name() == ast_string_constants()->undefined_string()) {
    1959       83190 :         builder()->LoadUndefined();
    1960             :       } else {
    1961             :         builder()->LoadGlobal(variable->raw_name(), feedback_index(slot),
    1962     1786890 :                               typeof_mode);
    1963             :       }
    1964             :       break;
    1965             :     }
    1966             :     case VariableLocation::CONTEXT: {
    1967     2850160 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    1968             :       ContextScope* context = execution_context()->Previous(depth);
    1969             :       Register context_reg;
    1970     2850159 :       if (context) {
    1971     2822984 :         context_reg = context->reg();
    1972             :         depth = 0;
    1973             :       } else {
    1974       27175 :         context_reg = execution_context()->reg();
    1975             :       }
    1976             : 
    1977             :       BytecodeArrayBuilder::ContextSlotMutability immutable =
    1978             :           (variable->maybe_assigned() == kNotAssigned)
    1979             :               ? BytecodeArrayBuilder::kImmutableSlot
    1980     2850159 :               : BytecodeArrayBuilder::kMutableSlot;
    1981             : 
    1982             :       builder()->LoadContextSlot(context_reg, variable->index(), depth,
    1983     2850159 :                                  immutable);
    1984     2850158 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    1985       59635 :         BuildThrowIfHole(variable);
    1986             :       }
    1987             :       break;
    1988             :     }
    1989             :     case VariableLocation::LOOKUP: {
    1990      483704 :       switch (variable->mode()) {
    1991             :         case DYNAMIC_LOCAL: {
    1992        7854 :           Variable* local_variable = variable->local_if_not_shadowed();
    1993             :           int depth =
    1994        3927 :               execution_context()->ContextChainDepth(local_variable->scope());
    1995             :           builder()->LoadLookupContextSlot(variable->raw_name(), typeof_mode,
    1996        3927 :                                            local_variable->index(), depth);
    1997        3927 :           if (hole_check_mode == HoleCheckMode::kRequired) {
    1998        1118 :             BuildThrowIfHole(variable);
    1999             :           }
    2000             :           break;
    2001             :         }
    2002             :         case DYNAMIC_GLOBAL: {
    2003             :           int depth =
    2004      463047 :               closure_scope()->ContextChainLengthUntilOutermostSloppyEval();
    2005             :           builder()->LoadLookupGlobalSlot(variable->raw_name(), typeof_mode,
    2006      463047 :                                           feedback_index(slot), depth);
    2007      463047 :           break;
    2008             :         }
    2009             :         default:
    2010       16730 :           builder()->LoadLookupSlot(variable->raw_name(), typeof_mode);
    2011             :       }
    2012             :       break;
    2013             :     }
    2014             :     case VariableLocation::MODULE: {
    2015        1615 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2016        1615 :       builder()->LoadModuleVariable(variable->index(), depth);
    2017        1615 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2018         922 :         BuildThrowIfHole(variable);
    2019             :       }
    2020             :       break;
    2021             :     }
    2022             :   }
    2023    12245703 : }
    2024             : 
    2025     1002541 : void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
    2026             :     Variable* variable, FeedbackSlot slot, HoleCheckMode hole_check_mode,
    2027             :     TypeofMode typeof_mode) {
    2028             :   ValueResultScope accumulator_result(this);
    2029     1002541 :   BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode);
    2030     1002541 : }
    2031             : 
    2032     7673956 : void BytecodeGenerator::BuildReturn() {
    2033     2557851 :   if (FLAG_trace) {
    2034             :     RegisterAllocationScope register_scope(this);
    2035           0 :     Register result = register_allocator()->NewRegister();
    2036             :     // Runtime returns {result} value, preserving accumulator.
    2037           0 :     builder()->StoreAccumulatorInRegister(result).CallRuntime(
    2038           0 :         Runtime::kTraceExit, result);
    2039             :   }
    2040     2557851 :   if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) {
    2041         400 :     builder()->CollectTypeProfile(info()->literal()->return_position());
    2042             :   }
    2043     2557854 :   builder()->Return();
    2044     2557858 : }
    2045             : 
    2046       24800 : void BytecodeGenerator::BuildAsyncReturn() {
    2047             :   RegisterAllocationScope register_scope(this);
    2048             : 
    2049        9920 :   if (IsAsyncGeneratorFunction(info()->literal()->kind())) {
    2050        2900 :     RegisterList args = register_allocator()->NewRegisterList(3);
    2051        2900 :     Register generator = args[0];
    2052        2900 :     Register result = args[1];
    2053        2900 :     Register done = args[2];
    2054             : 
    2055        2900 :     builder()->StoreAccumulatorInRegister(result);
    2056             :     Variable* var_generator_object = closure_scope()->generator_object_var();
    2057             :     DCHECK_NOT_NULL(var_generator_object);
    2058             :     BuildVariableLoad(var_generator_object, FeedbackSlot::Invalid(),
    2059        2900 :                       HoleCheckMode::kElided);
    2060             :     builder()
    2061        2900 :         ->StoreAccumulatorInRegister(generator)
    2062        2900 :         .LoadTrue()
    2063        2900 :         .StoreAccumulatorInRegister(done)
    2064        2900 :         .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args);
    2065             :   } else {
    2066             :     DCHECK(IsAsyncFunction(info()->literal()->kind()));
    2067        2060 :     RegisterList args = register_allocator()->NewRegisterList(3);
    2068        2060 :     Register receiver = args[0];
    2069        2060 :     Register promise = args[1];
    2070        2060 :     Register return_value = args[2];
    2071        2060 :     builder()->StoreAccumulatorInRegister(return_value);
    2072             : 
    2073             :     Variable* var_promise = closure_scope()->promise_var();
    2074             :     DCHECK_NOT_NULL(var_promise);
    2075             :     BuildVariableLoad(var_promise, FeedbackSlot::Invalid(),
    2076        2060 :                       HoleCheckMode::kElided);
    2077             :     builder()
    2078        2060 :         ->StoreAccumulatorInRegister(promise)
    2079        2060 :         .LoadUndefined()
    2080        2060 :         .StoreAccumulatorInRegister(receiver)
    2081        2060 :         .CallJSRuntime(Context::PROMISE_RESOLVE_INDEX, args)
    2082        2060 :         .LoadAccumulatorWithRegister(promise);
    2083             :   }
    2084             : 
    2085        4960 :   BuildReturn();
    2086        4960 : }
    2087             : 
    2088       48266 : void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); }
    2089             : 
    2090       23706 : void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) {
    2091             :   RegisterAllocationScope register_scope(this);
    2092       11853 :   Register reason = register_allocator()->NewRegister();
    2093             :   builder()
    2094       23706 :       ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason)))
    2095       11853 :       .StoreAccumulatorInRegister(reason)
    2096       11853 :       .CallRuntime(Runtime::kAbort, reason);
    2097       11853 : }
    2098             : 
    2099      218690 : void BytecodeGenerator::BuildThrowReferenceError(const AstRawString* name) {
    2100             :   RegisterAllocationScope register_scope(this);
    2101      109345 :   Register name_reg = register_allocator()->NewRegister();
    2102      109345 :   builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime(
    2103      109345 :       Runtime::kThrowReferenceError, name_reg);
    2104      109345 : }
    2105             : 
    2106      517236 : void BytecodeGenerator::BuildThrowIfHole(Variable* variable) {
    2107             :   // TODO(interpreter): Can the parser reduce the number of checks
    2108             :   // performed? Or should there be a ThrowIfHole bytecode.
    2109             :   BytecodeLabel no_reference_error;
    2110      129309 :   builder()->JumpIfNotHole(&no_reference_error);
    2111             : 
    2112      129309 :   if (variable->is_this()) {
    2113             :     DCHECK(variable->mode() == CONST);
    2114       19964 :     builder()->CallRuntime(Runtime::kThrowSuperNotCalled);
    2115             :   } else {
    2116      109345 :     BuildThrowReferenceError(variable->raw_name());
    2117             :   }
    2118             : 
    2119      129309 :   builder()->Bind(&no_reference_error);
    2120      129309 : }
    2121             : 
    2122       35258 : void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
    2123        2523 :                                                             Token::Value op) {
    2124       37781 :   if (variable->is_this() && variable->mode() == CONST && op == Token::INIT) {
    2125             :     // Perform an initialization check for 'this'. 'this' variable is the
    2126             :     // only variable able to trigger bind operations outside the TDZ
    2127             :     // via 'super' calls.
    2128             :     BytecodeLabel no_reference_error, reference_error;
    2129             :     builder()
    2130        2523 :         ->JumpIfNotHole(&reference_error)
    2131        2523 :         .Jump(&no_reference_error)
    2132        2523 :         .Bind(&reference_error)
    2133        2523 :         .CallRuntime(Runtime::kThrowSuperAlreadyCalledError)
    2134        2523 :         .Bind(&no_reference_error);
    2135             :   } else {
    2136             :     // Perform an initialization check for let/const declared variables.
    2137             :     // E.g. let x = (x = 20); is not allowed.
    2138             :     DCHECK(IsLexicalVariableMode(variable->mode()));
    2139       32735 :     BuildThrowIfHole(variable);
    2140             :   }
    2141       35258 : }
    2142             : 
    2143    12689321 : void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
    2144             :                                                 Token::Value op,
    2145             :                                                 FeedbackSlot slot,
    2146     7796684 :                                                 HoleCheckMode hole_check_mode) {
    2147             :   VariableMode mode = variable->mode();
    2148             :   RegisterAllocationScope assignment_register_scope(this);
    2149             :   BytecodeLabel end_label;
    2150     5590719 :   switch (variable->location()) {
    2151             :     case VariableLocation::PARAMETER:
    2152             :     case VariableLocation::LOCAL: {
    2153             :       Register destination;
    2154     3219804 :       if (VariableLocation::PARAMETER == variable->location()) {
    2155       33641 :         if (variable->IsReceiver()) {
    2156        2443 :           destination = builder()->Receiver();
    2157             :         } else {
    2158       31198 :           destination = builder()->Parameter(variable->index());
    2159             :         }
    2160             :       } else {
    2161     3186163 :         destination = builder()->Local(variable->index());
    2162             :       }
    2163             : 
    2164     3219803 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2165             :         // Load destination to check for hole.
    2166        5427 :         Register value_temp = register_allocator()->NewRegister();
    2167             :         builder()
    2168        5427 :             ->StoreAccumulatorInRegister(value_temp)
    2169        5427 :             .LoadAccumulatorWithRegister(destination);
    2170             : 
    2171        5427 :         BuildHoleCheckForVariableAssignment(variable, op);
    2172        5427 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2173             :       }
    2174             : 
    2175     3219803 :       if (mode != CONST || op == Token::INIT) {
    2176     3214672 :         builder()->StoreAccumulatorInRegister(destination);
    2177        5131 :       } else if (variable->throw_on_const_assignment(language_mode())) {
    2178        5108 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2179             :       }
    2180             :       break;
    2181             :     }
    2182             :     case VariableLocation::UNALLOCATED: {
    2183             :       builder()->StoreGlobal(variable->raw_name(), feedback_index(slot),
    2184      828549 :                              language_mode());
    2185      828549 :       break;
    2186             :     }
    2187             :     case VariableLocation::CONTEXT: {
    2188     1500926 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2189             :       ContextScope* context = execution_context()->Previous(depth);
    2190             :       Register context_reg;
    2191             : 
    2192     1500926 :       if (context) {
    2193     1493337 :         context_reg = context->reg();
    2194             :         depth = 0;
    2195             :       } else {
    2196        7589 :         context_reg = execution_context()->reg();
    2197             :       }
    2198             : 
    2199     1500926 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2200             :         // Load destination to check for hole.
    2201       29733 :         Register value_temp = register_allocator()->NewRegister();
    2202             :         builder()
    2203       29733 :             ->StoreAccumulatorInRegister(value_temp)
    2204             :             .LoadContextSlot(context_reg, variable->index(), depth,
    2205       29733 :                              BytecodeArrayBuilder::kMutableSlot);
    2206             : 
    2207       29733 :         BuildHoleCheckForVariableAssignment(variable, op);
    2208       29733 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2209             :       }
    2210             : 
    2211     1500926 :       if (mode != CONST || op == Token::INIT) {
    2212     1476389 :         builder()->StoreContextSlot(context_reg, variable->index(), depth);
    2213       24537 :       } else if (variable->throw_on_const_assignment(language_mode())) {
    2214       24513 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2215             :       }
    2216             :       break;
    2217             :     }
    2218             :     case VariableLocation::LOOKUP: {
    2219       39469 :       builder()->StoreLookupSlot(variable->raw_name(), language_mode());
    2220       39469 :       break;
    2221             :     }
    2222             :     case VariableLocation::MODULE: {
    2223             :       DCHECK(IsDeclaredVariableMode(mode));
    2224             : 
    2225        1971 :       if (mode == CONST && op != Token::INIT) {
    2226         154 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2227         154 :         break;
    2228             :       }
    2229             : 
    2230             :       // If we don't throw above, we know that we're dealing with an
    2231             :       // export because imports are const and we do not generate initializing
    2232             :       // assignments for them.
    2233             :       DCHECK(variable->IsExport());
    2234             : 
    2235        1817 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2236        1817 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2237          98 :         Register value_temp = register_allocator()->NewRegister();
    2238             :         builder()
    2239          98 :             ->StoreAccumulatorInRegister(value_temp)
    2240          98 :             .LoadModuleVariable(variable->index(), depth);
    2241          98 :         BuildHoleCheckForVariableAssignment(variable, op);
    2242          98 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2243             :       }
    2244        1817 :       builder()->StoreModuleVariable(variable->index(), depth);
    2245        1817 :       break;
    2246             :     }
    2247     5590726 :   }
    2248     5590724 : }
    2249             : 
    2250    36818245 : void BytecodeGenerator::VisitAssignment(Assignment* expr) {
    2251             :   DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
    2252             :   Register object, key;
    2253             :   RegisterList super_property_args;
    2254             :   const AstRawString* name;
    2255             : 
    2256             :   // Left-hand side can only be a property, a global or a variable slot.
    2257     9662627 :   Property* property = expr->target()->AsProperty();
    2258     6590882 :   LhsKind assign_type = Property::GetAssignType(property);
    2259             : 
    2260             :   // Evaluate LHS expression.
    2261     6590877 :   switch (assign_type) {
    2262             :     case VARIABLE:
    2263             :       // Nothing to do to evaluate variable assignment LHS.
    2264             :       break;
    2265             :     case NAMED_PROPERTY: {
    2266     1454576 :       object = VisitForRegisterValue(property->obj());
    2267     2909152 :       name = property->key()->AsLiteral()->AsRawPropertyName();
    2268     1454576 :       break;
    2269             :     }
    2270             :     case KEYED_PROPERTY: {
    2271       80645 :       object = VisitForRegisterValue(property->obj());
    2272       80645 :       key = VisitForRegisterValue(property->key());
    2273       80645 :       break;
    2274             :     }
    2275             :     case NAMED_SUPER_PROPERTY: {
    2276         260 :       super_property_args = register_allocator()->NewRegisterList(4);
    2277         520 :       SuperPropertyReference* super_property =
    2278         260 :           property->obj()->AsSuperPropertyReference();
    2279         260 :       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
    2280             :       VisitForRegisterValue(super_property->home_object(),
    2281         260 :                             super_property_args[1]);
    2282             :       builder()
    2283         780 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    2284         260 :           .StoreAccumulatorInRegister(super_property_args[2]);
    2285         260 :       break;
    2286             :     }
    2287             :     case KEYED_SUPER_PROPERTY: {
    2288         397 :       super_property_args = register_allocator()->NewRegisterList(4);
    2289         794 :       SuperPropertyReference* super_property =
    2290         397 :           property->obj()->AsSuperPropertyReference();
    2291         397 :       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
    2292             :       VisitForRegisterValue(super_property->home_object(),
    2293         397 :                             super_property_args[1]);
    2294         397 :       VisitForRegisterValue(property->key(), super_property_args[2]);
    2295         397 :       break;
    2296             :     }
    2297             :   }
    2298             : 
    2299             :   // Evaluate the value and potentially handle compound assignments by loading
    2300             :   // the left-hand side value and performing a binary operation.
    2301     6590877 :   if (expr->is_compound()) {
    2302       92271 :     switch (assign_type) {
    2303             :       case VARIABLE: {
    2304      273150 :         VariableProxy* proxy = expr->target()->AsVariableProxy();
    2305             :         BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
    2306       91050 :                           proxy->hole_check_mode());
    2307       91050 :         break;
    2308             :       }
    2309             :       case NAMED_PROPERTY: {
    2310             :         FeedbackSlot slot = property->PropertyFeedbackSlot();
    2311         456 :         builder()->LoadNamedProperty(object, name, feedback_index(slot));
    2312             :         break;
    2313             :       }
    2314             :       case KEYED_PROPERTY: {
    2315             :         // Key is already in accumulator at this point due to evaluating the
    2316             :         // LHS above.
    2317             :         FeedbackSlot slot = property->PropertyFeedbackSlot();
    2318         693 :         builder()->LoadKeyedProperty(object, feedback_index(slot));
    2319             :         break;
    2320             :       }
    2321             :       case NAMED_SUPER_PROPERTY: {
    2322             :         builder()->CallRuntime(Runtime::kLoadFromSuper,
    2323          24 :                                super_property_args.Truncate(3));
    2324          24 :         break;
    2325             :       }
    2326             :       case KEYED_SUPER_PROPERTY: {
    2327             :         builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
    2328          48 :                                super_property_args.Truncate(3));
    2329          48 :         break;
    2330             :       }
    2331             :     }
    2332             :     FeedbackSlot slot = expr->binary_operation()->BinaryOperationFeedbackSlot();
    2333       92271 :     if (expr->value()->IsSmiLiteral()) {
    2334             :       builder()->BinaryOperationSmiLiteral(
    2335             :           expr->binary_op(), expr->value()->AsLiteral()->AsSmiLiteral(),
    2336       73815 :           feedback_index(slot));
    2337             :     } else {
    2338       67666 :       Register old_value = register_allocator()->NewRegister();
    2339       67666 :       builder()->StoreAccumulatorInRegister(old_value);
    2340       67666 :       VisitForAccumulatorValue(expr->value());
    2341             :       builder()->BinaryOperation(expr->binary_op(), old_value,
    2342      135332 :                                  feedback_index(slot));
    2343             :     }
    2344             :   } else {
    2345     6498606 :     VisitForAccumulatorValue(expr->value());
    2346             :   }
    2347             : 
    2348             :   // Store the value.
    2349             :   builder()->SetExpressionPosition(expr);
    2350             :   FeedbackSlot slot = expr->AssignmentSlot();
    2351     6590882 :   switch (assign_type) {
    2352             :     case VARIABLE: {
    2353             :       // TODO(oth): The BuildVariableAssignment() call is hard to reason about.
    2354             :       // Is the value in the accumulator safe? Yes, but scary.
    2355    15165006 :       VariableProxy* proxy = expr->target()->AsVariableProxy();
    2356             :       BuildVariableAssignment(proxy->var(), expr->op(), slot,
    2357     5055001 :                               proxy->hole_check_mode());
    2358     5055007 :       break;
    2359             :     }
    2360             :     case NAMED_PROPERTY:
    2361             :       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    2362     1454576 :                                     language_mode());
    2363     1454576 :       break;
    2364             :     case KEYED_PROPERTY:
    2365             :       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    2366       80645 :                                     language_mode());
    2367       80645 :       break;
    2368             :     case NAMED_SUPER_PROPERTY: {
    2369             :       builder()
    2370         260 :           ->StoreAccumulatorInRegister(super_property_args[3])
    2371         260 :           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
    2372         260 :       break;
    2373             :     }
    2374             :     case KEYED_SUPER_PROPERTY: {
    2375             :       builder()
    2376         397 :           ->StoreAccumulatorInRegister(super_property_args[3])
    2377         397 :           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
    2378         397 :       break;
    2379             :     }
    2380             :   }
    2381     6590885 : }
    2382             : 
    2383      416493 : void BytecodeGenerator::VisitSuspend(Suspend* expr) {
    2384             :   builder()->SetExpressionPosition(expr);
    2385       19833 :   Register value = VisitForRegisterValue(expr->expression());
    2386             : 
    2387       19833 :   Register generator = VisitForRegisterValue(expr->generator_object());
    2388             : 
    2389             :   // Save context, registers, and state. Then return.
    2390             :   builder()
    2391       19833 :       ->LoadLiteral(Smi::FromInt(expr->suspend_id()))
    2392       19833 :       .SuspendGenerator(generator, expr->flags());
    2393             : 
    2394       19833 :   if (expr->IsNonInitialAsyncGeneratorYield()) {
    2395             :     // AsyncGenerator yields (with the exception of the initial yield) delegate
    2396             :     // to AsyncGeneratorResolve(), implemented via the runtime call below.
    2397         402 :     RegisterList args = register_allocator()->NewRegisterList(3);
    2398             : 
    2399             :     // AsyncGeneratorYield:
    2400             :     // perform AsyncGeneratorResolve(<generator>, <value>, false).
    2401             :     builder()
    2402         402 :         ->MoveRegister(generator, args[0])
    2403         402 :         .MoveRegister(value, args[1])
    2404         402 :         .LoadFalse()
    2405         402 :         .StoreAccumulatorInRegister(args[2])
    2406         402 :         .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args);
    2407             :   } else {
    2408       19431 :     builder()->LoadAccumulatorWithRegister(value);
    2409             :   }
    2410       19833 :   builder()->Return();  // Hard return (ignore any finally blocks).
    2411             : 
    2412       39666 :   builder()->Bind(&(generator_resume_points_[expr->suspend_id()]));
    2413             :   // Upon resume, we continue here.
    2414             : 
    2415             :   {
    2416             :     RegisterAllocationScope register_scope(this);
    2417             : 
    2418             :     // Update state to indicate that we have finished resuming. Loop headers
    2419             :     // rely on this.
    2420             :     builder()
    2421       19833 :         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    2422       19833 :         .StoreAccumulatorInRegister(generator_state_);
    2423             : 
    2424       19833 :     Register input = register_allocator()->NewRegister();
    2425             : 
    2426             :     // When resuming an Async Generator from an Await expression, the sent
    2427             :     // value is in the [[await_input_or_debug_pos]] slot. Otherwise, the sent
    2428             :     // value is in the [[input_or_debug_pos]] slot.
    2429             :     Runtime::FunctionId get_generator_input =
    2430        2096 :         expr->is_async_generator() && expr->is_await()
    2431             :             ? Runtime::kInlineAsyncGeneratorGetAwaitInputOrDebugPos
    2432       19833 :             : Runtime::kInlineGeneratorGetInputOrDebugPos;
    2433             : 
    2434             :     builder()
    2435       19833 :         ->CallRuntime(get_generator_input, generator)
    2436       19833 :         .StoreAccumulatorInRegister(input);
    2437             : 
    2438       19833 :     Register resume_mode = register_allocator()->NewRegister();
    2439             :     builder()
    2440       19833 :         ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator)
    2441       19833 :         .StoreAccumulatorInRegister(resume_mode);
    2442             : 
    2443             :     // Now dispatch on resume mode.
    2444             : 
    2445             :     BytecodeLabel resume_with_next;
    2446             :     BytecodeLabel resume_with_return;
    2447             :     BytecodeLabel resume_with_throw;
    2448             : 
    2449             :     builder()
    2450       19833 :         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
    2451       19833 :         .CompareOperation(Token::EQ_STRICT, resume_mode)
    2452       19833 :         .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_next)
    2453       19833 :         .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow))
    2454       19833 :         .CompareOperation(Token::EQ_STRICT, resume_mode)
    2455       19833 :         .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_throw)
    2456       19833 :         .Jump(&resume_with_return);
    2457             : 
    2458       19833 :     builder()->Bind(&resume_with_return);
    2459             :     {
    2460       19833 :       if (expr->is_async_generator()) {
    2461             :         // Async generator methods will produce the iter result object.
    2462        2096 :         builder()->LoadAccumulatorWithRegister(input);
    2463             :         execution_control()->AsyncReturnAccumulator();
    2464             :       } else {
    2465       17737 :         RegisterList args = register_allocator()->NewRegisterList(2);
    2466             :         builder()
    2467       17737 :             ->MoveRegister(input, args[0])
    2468       17737 :             .LoadTrue()
    2469       17737 :             .StoreAccumulatorInRegister(args[1])
    2470       17737 :             .CallRuntime(Runtime::kInlineCreateIterResultObject, args);
    2471             :         execution_control()->ReturnAccumulator();
    2472             :       }
    2473             :     }
    2474             : 
    2475       19833 :     builder()->Bind(&resume_with_throw);
    2476             :     builder()->SetExpressionPosition(expr);
    2477       19833 :     builder()->LoadAccumulatorWithRegister(input);
    2478       19833 :     if (expr->rethrow_on_exception()) {
    2479        8930 :       builder()->ReThrow();
    2480             :     } else {
    2481       10903 :       builder()->Throw();
    2482             :     }
    2483             : 
    2484       19833 :     builder()->Bind(&resume_with_next);
    2485       19833 :     builder()->LoadAccumulatorWithRegister(input);
    2486             :   }
    2487       19833 : }
    2488             : 
    2489      225576 : void BytecodeGenerator::VisitThrow(Throw* expr) {
    2490      112788 :   VisitForAccumulatorValue(expr->exception());
    2491             :   builder()->SetExpressionPosition(expr);
    2492      112788 :   builder()->Throw();
    2493      112788 : }
    2494             : 
    2495    15861321 : void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
    2496     3965775 :   LhsKind property_kind = Property::GetAssignType(expr);
    2497             :   FeedbackSlot slot = expr->PropertyFeedbackSlot();
    2498             :   builder()->SetExpressionPosition(expr);
    2499     3965778 :   switch (property_kind) {
    2500             :     case VARIABLE:
    2501           0 :       UNREACHABLE();
    2502             :     case NAMED_PROPERTY: {
    2503             :       builder()->LoadNamedProperty(
    2504             :           obj, expr->key()->AsLiteral()->AsRawPropertyName(),
    2505    10956296 :           feedback_index(slot));
    2506     3652095 :       break;
    2507             :     }
    2508             :     case KEYED_PROPERTY: {
    2509      312785 :       VisitForAccumulatorValue(expr->key());
    2510      312785 :       builder()->LoadKeyedProperty(obj, feedback_index(slot));
    2511      312785 :       break;
    2512             :     }
    2513             :     case NAMED_SUPER_PROPERTY:
    2514         474 :       VisitNamedSuperPropertyLoad(expr, Register::invalid_value());
    2515         474 :       break;
    2516             :     case KEYED_SUPER_PROPERTY:
    2517         420 :       VisitKeyedSuperPropertyLoad(expr, Register::invalid_value());
    2518         420 :       break;
    2519             :   }
    2520     3965773 : }
    2521             : 
    2522      966782 : void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj,
    2523             :                                                      Property* expr,
    2524      966783 :                                                      Register destination) {
    2525             :   ValueResultScope result_scope(this);
    2526      966782 :   VisitPropertyLoad(obj, expr);
    2527      966783 :   builder()->StoreAccumulatorInRegister(destination);
    2528      966783 : }
    2529             : 
    2530        2706 : void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
    2531        1330 :                                                     Register opt_receiver_out) {
    2532             :   RegisterAllocationScope register_scope(this);
    2533        1804 :   SuperPropertyReference* super_property =
    2534         902 :       property->obj()->AsSuperPropertyReference();
    2535         902 :   RegisterList args = register_allocator()->NewRegisterList(3);
    2536         902 :   VisitForRegisterValue(super_property->this_var(), args[0]);
    2537         902 :   VisitForRegisterValue(super_property->home_object(), args[1]);
    2538             :   builder()
    2539        2706 :       ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    2540         902 :       .StoreAccumulatorInRegister(args[2])
    2541         902 :       .CallRuntime(Runtime::kLoadFromSuper, args);
    2542             : 
    2543         902 :   if (opt_receiver_out.is_valid()) {
    2544         428 :     builder()->MoveRegister(args[0], opt_receiver_out);
    2545         902 :   }
    2546         902 : }
    2547             : 
    2548        1374 : void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
    2549         496 :                                                     Register opt_receiver_out) {
    2550             :   RegisterAllocationScope register_scope(this);
    2551         916 :   SuperPropertyReference* super_property =
    2552         458 :       property->obj()->AsSuperPropertyReference();
    2553         458 :   RegisterList args = register_allocator()->NewRegisterList(3);
    2554         458 :   VisitForRegisterValue(super_property->this_var(), args[0]);
    2555         458 :   VisitForRegisterValue(super_property->home_object(), args[1]);
    2556         458 :   VisitForRegisterValue(property->key(), args[2]);
    2557         458 :   builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, args);
    2558             : 
    2559         458 :   if (opt_receiver_out.is_valid()) {
    2560          38 :     builder()->MoveRegister(args[0], opt_receiver_out);
    2561         458 :   }
    2562         458 : }
    2563             : 
    2564     5997096 : void BytecodeGenerator::VisitProperty(Property* expr) {
    2565     2998995 :   LhsKind property_kind = Property::GetAssignType(expr);
    2566     2998995 :   if (property_kind != NAMED_SUPER_PROPERTY &&
    2567             :       property_kind != KEYED_SUPER_PROPERTY) {
    2568     2998101 :     Register obj = VisitForRegisterValue(expr->obj());
    2569     2998100 :     VisitPropertyLoad(obj, expr);
    2570             :   } else {
    2571         894 :     VisitPropertyLoad(Register::invalid_value(), expr);
    2572             :   }
    2573     2998992 : }
    2574             : 
    2575     3566881 : void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args,
    2576             :                                        RegisterList* arg_regs) {
    2577             :   // Visit arguments.
    2578    22962454 :   for (int i = 0; i < static_cast<int>(args->length()); i++) {
    2579    19395574 :     VisitAndPushIntoRegisterList(args->at(i), arg_regs);
    2580             :   }
    2581     3566880 : }
    2582             : 
    2583    17873030 : void BytecodeGenerator::VisitCall(Call* expr) {
    2584             :   Expression* callee_expr = expr->expression();
    2585     2402286 :   Call::CallType call_type = expr->GetCallType();
    2586             : 
    2587     2402295 :   if (call_type == Call::SUPER_CALL) {
    2588     2406395 :     return VisitCallSuper(expr);
    2589             :   }
    2590             : 
    2591             :   // Grow the args list as we visit receiver / arguments to avoid allocating all
    2592             :   // the registers up-front. Otherwise these registers are unavailable during
    2593             :   // receiver / argument visiting and we can end up with memory leaks due to
    2594             :   // registers keeping objects alive.
    2595     2398194 :   Register callee = register_allocator()->NewRegister();
    2596     2398194 :   RegisterList args = register_allocator()->NewGrowableRegisterList();
    2597             : 
    2598             :   bool implicit_undefined_receiver = false;
    2599     2398194 :   bool is_tail_call = (expr->tail_call_mode() == TailCallMode::kAllow);
    2600             :   // When a call contains a spread, a Call AST node is only created if there is
    2601             :   // exactly one spread, and it is the last argument.
    2602     2398194 :   bool is_spread_call = expr->only_last_arg_is_spread();
    2603             : 
    2604             :   // TODO(petermarshall): We have a lot of call bytecodes that are very similar,
    2605             :   // see if we can reduce the number by adding a separate argument which
    2606             :   // specifies the call type (e.g., property, spread, tailcall, etc.).
    2607             : 
    2608             :   // Prepare the callee and the receiver to the function call. This depends on
    2609             :   // the semantics of the underlying call type.
    2610     2398193 :   switch (call_type) {
    2611             :     case Call::NAMED_PROPERTY_CALL:
    2612             :     case Call::KEYED_PROPERTY_CALL: {
    2613     1933564 :       Property* property = callee_expr->AsProperty();
    2614      966781 :       VisitAndPushIntoRegisterList(property->obj(), &args);
    2615      966783 :       VisitPropertyLoadForRegister(args.last_register(), property, callee);
    2616      966783 :       break;
    2617             :     }
    2618             :     case Call::GLOBAL_CALL: {
    2619             :       // Receiver is undefined for global calls.
    2620      661329 :       if (!is_tail_call && !is_spread_call) {
    2621             :         implicit_undefined_receiver = true;
    2622             :       } else {
    2623             :         // TODO(leszeks): There's no special bytecode for tail calls or spread
    2624             :         // calls with an undefined receiver, so just push undefined ourselves.
    2625         254 :         BuildPushUndefinedIntoRegisterList(&args);
    2626             :       }
    2627             :       // Load callee as a global variable.
    2628     1983987 :       VariableProxy* proxy = callee_expr->AsVariableProxy();
    2629             :       BuildVariableLoadForAccumulatorValue(proxy->var(),
    2630             :                                            proxy->VariableFeedbackSlot(),
    2631      661329 :                                            proxy->hole_check_mode());
    2632      661329 :       builder()->StoreAccumulatorInRegister(callee);
    2633      661329 :       break;
    2634             :     }
    2635             :     case Call::WITH_CALL: {
    2636        2754 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    2637             :       DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot());
    2638             :       {
    2639             :         RegisterAllocationScope inner_register_scope(this);
    2640        2754 :         Register name = register_allocator()->NewRegister();
    2641             : 
    2642             :         // Call %LoadLookupSlotForCall to get the callee and receiver.
    2643             :         DCHECK(Register::AreContiguous(callee, receiver));
    2644             :         RegisterList result_pair(callee.index(), 2);
    2645             :         USE(receiver);
    2646             : 
    2647        5508 :         Variable* variable = callee_expr->AsVariableProxy()->var();
    2648             :         builder()
    2649        2754 :             ->LoadLiteral(variable->raw_name())
    2650        2754 :             .StoreAccumulatorInRegister(name)
    2651             :             .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name,
    2652        2754 :                                 result_pair);
    2653             :       }
    2654             :       break;
    2655             :     }
    2656             :     case Call::OTHER_CALL: {
    2657             :       // Receiver is undefined for other calls.
    2658      766858 :       if (!is_tail_call && !is_spread_call) {
    2659             :         implicit_undefined_receiver = true;
    2660             :       } else {
    2661             :         // TODO(leszeks): There's no special bytecode for tail calls or spread
    2662             :         // calls with an undefined receiver, so just push undefined ourselves.
    2663        1011 :         BuildPushUndefinedIntoRegisterList(&args);
    2664             :       }
    2665      766858 :       VisitForRegisterValue(callee_expr, callee);
    2666      766863 :       break;
    2667             :     }
    2668             :     case Call::NAMED_SUPER_PROPERTY_CALL: {
    2669         428 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    2670         428 :       Property* property = callee_expr->AsProperty();
    2671         428 :       VisitNamedSuperPropertyLoad(property, receiver);
    2672         428 :       builder()->StoreAccumulatorInRegister(callee);
    2673             :       break;
    2674             :     }
    2675             :     case Call::KEYED_SUPER_PROPERTY_CALL: {
    2676          38 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    2677          38 :       Property* property = callee_expr->AsProperty();
    2678          38 :       VisitKeyedSuperPropertyLoad(property, receiver);
    2679          38 :       builder()->StoreAccumulatorInRegister(callee);
    2680             :       break;
    2681             :     }
    2682             :     case Call::SUPER_CALL:
    2683           0 :       UNREACHABLE();
    2684             :       break;
    2685             :   }
    2686             : 
    2687             :   // Evaluate all arguments to the function call and store in sequential args
    2688             :   // registers.
    2689     2398198 :   VisitArguments(expr->arguments(), &args);
    2690     2398193 :   int reciever_arg_count = implicit_undefined_receiver ? 0 : 1;
    2691     4796386 :   CHECK_EQ(reciever_arg_count + expr->arguments()->length(),
    2692             :            args.register_count());
    2693             : 
    2694             :   // Resolve callee for a potential direct eval call. This block will mutate the
    2695             :   // callee value.
    2696     2398193 :   if (expr->is_possibly_eval() && expr->arguments()->length() > 0) {
    2697             :     RegisterAllocationScope inner_register_scope(this);
    2698             :     // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
    2699             :     // strings and function closure, and loading language and
    2700             :     // position.
    2701      278020 :     Register first_arg = args[reciever_arg_count];
    2702      139010 :     RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
    2703             :     builder()
    2704      139010 :         ->MoveRegister(callee, runtime_call_args[0])
    2705      139010 :         .MoveRegister(first_arg, runtime_call_args[1])
    2706      278020 :         .MoveRegister(Register::function_closure(), runtime_call_args[2])
    2707      278020 :         .LoadLiteral(Smi::FromInt(language_mode()))
    2708      139010 :         .StoreAccumulatorInRegister(runtime_call_args[3])
    2709      278020 :         .LoadLiteral(Smi::FromInt(current_scope()->start_position()))
    2710      139010 :         .StoreAccumulatorInRegister(runtime_call_args[4])
    2711      278020 :         .LoadLiteral(Smi::FromInt(expr->position()))
    2712      139010 :         .StoreAccumulatorInRegister(runtime_call_args[5]);
    2713             : 
    2714             :     // Call ResolvePossiblyDirectEval and modify the callee.
    2715             :     builder()
    2716      139010 :         ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
    2717      139010 :         .StoreAccumulatorInRegister(callee);
    2718             :   }
    2719             : 
    2720             :   builder()->SetExpressionPosition(expr);
    2721             : 
    2722             :   int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
    2723             : 
    2724     2398193 :   if (is_spread_call) {
    2725             :     DCHECK(!is_tail_call);
    2726             :     DCHECK(!implicit_undefined_receiver);
    2727        1836 :     builder()->CallWithSpread(callee, args);
    2728     2396357 :   } else if (is_tail_call) {
    2729             :     DCHECK(!implicit_undefined_receiver);
    2730        1144 :     builder()->TailCall(callee, args, feedback_slot_index);
    2731     2395213 :   } else if (call_type == Call::NAMED_PROPERTY_CALL ||
    2732             :              call_type == Call::KEYED_PROPERTY_CALL) {
    2733             :     DCHECK(!implicit_undefined_receiver);
    2734      965102 :     builder()->CallProperty(callee, args, feedback_slot_index);
    2735     1430111 :   } else if (implicit_undefined_receiver) {
    2736     1426924 :     builder()->CallUndefinedReceiver(callee, args, feedback_slot_index);
    2737             :   } else {
    2738        3187 :     builder()->CallAnyReceiver(callee, args, feedback_slot_index);
    2739             :   }
    2740             : }
    2741             : 
    2742       28707 : void BytecodeGenerator::VisitCallSuper(Call* expr) {
    2743             :   RegisterAllocationScope register_scope(this);
    2744       12303 :   SuperCallReference* super = expr->expression()->AsSuperCallReference();
    2745             : 
    2746             :   // Prepare the constructor to the super call.
    2747        4101 :   VisitForAccumulatorValue(super->this_function_var());
    2748        4101 :   Register constructor = register_allocator()->NewRegister();
    2749        4101 :   builder()->GetSuperConstructor(constructor);
    2750             : 
    2751             :   ZoneList<Expression*>* args = expr->arguments();
    2752        4101 :   RegisterList args_regs = register_allocator()->NewGrowableRegisterList();
    2753        4101 :   VisitArguments(args, &args_regs);
    2754             :   // The new target is loaded into the accumulator from the
    2755             :   // {new.target} variable.
    2756        4101 :   VisitForAccumulatorValue(super->new_target_var());
    2757             :   builder()->SetExpressionPosition(expr);
    2758             : 
    2759             :   // When a super call contains a spread, a CallSuper AST node is only created
    2760             :   // if there is exactly one spread, and it is the last argument.
    2761        4101 :   if (expr->only_last_arg_is_spread()) {
    2762             :     // TODO(petermarshall): Collect type on the feedback slot.
    2763        3061 :     builder()->ConstructWithSpread(constructor, args_regs);
    2764             :   } else {
    2765             :     // Call construct.
    2766             :     // TODO(turbofan): For now we do gather feedback on super constructor
    2767             :     // calls, utilizing the existing machinery to inline the actual call
    2768             :     // target and the JSCreate for the implicit receiver allocation. This
    2769             :     // is not an ideal solution for super constructor calls, but it gets
    2770             :     // the job done for now. In the long run we might want to revisit this
    2771             :     // and come up with a better way.
    2772             :     int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
    2773        1040 :     builder()->Construct(constructor, args_regs, feedback_slot_index);
    2774        4101 :   }
    2775        4101 : }
    2776             : 
    2777     1106675 : void BytecodeGenerator::VisitCallNew(CallNew* expr) {
    2778      221335 :   Register constructor = VisitForRegisterValue(expr->expression());
    2779      221335 :   RegisterList args = register_allocator()->NewGrowableRegisterList();
    2780      221335 :   VisitArguments(expr->arguments(), &args);
    2781             : 
    2782             :   // The accumulator holds new target which is the same as the
    2783             :   // constructor for CallNew.
    2784             :   builder()->SetExpressionPosition(expr);
    2785      221335 :   builder()->LoadAccumulatorWithRegister(constructor);
    2786             : 
    2787      221335 :   if (expr->only_last_arg_is_spread()) {
    2788             :     // TODO(petermarshall): Collect type on the feedback slot.
    2789         146 :     builder()->ConstructWithSpread(constructor, args);
    2790             :   } else {
    2791             :     builder()->Construct(constructor, args,
    2792      221189 :                          feedback_index(expr->CallNewFeedbackSlot()));
    2793             :   }
    2794      221335 : }
    2795             : 
    2796     3647703 : void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    2797      943251 :   if (expr->is_jsruntime()) {
    2798      125299 :     RegisterList args = register_allocator()->NewGrowableRegisterList();
    2799             :     // Allocate a register for the receiver and load it with undefined.
    2800             :     // TODO(leszeks): If CallJSRuntime always has an undefined receiver, use the
    2801             :     // same mechanism as CallUndefinedReceiver.
    2802      125299 :     BuildPushUndefinedIntoRegisterList(&args);
    2803      125299 :     VisitArguments(expr->arguments(), &args);
    2804      125299 :     builder()->CallJSRuntime(expr->context_index(), args);
    2805             :   } else {
    2806             :     // Evaluate all arguments to the runtime call.
    2807      817952 :     RegisterList args = register_allocator()->NewGrowableRegisterList();
    2808      817952 :     VisitArguments(expr->arguments(), &args);
    2809      817951 :     Runtime::FunctionId function_id = expr->function()->function_id;
    2810      817951 :     builder()->CallRuntime(function_id, args);
    2811             :   }
    2812      943251 : }
    2813             : 
    2814       54278 : void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
    2815       27139 :   VisitForEffect(expr->expression());
    2816       27139 :   builder()->LoadUndefined();
    2817           0 : }
    2818             : 
    2819      212620 : void BytecodeGenerator::VisitForTypeOfValue(Expression* expr) {
    2820      212620 :   if (expr->IsVariableProxy()) {
    2821             :     // Typeof does not throw a reference error on global variables, hence we
    2822             :     // perform a non-contextual load in case the operand is a variable proxy.
    2823      596283 :     VariableProxy* proxy = expr->AsVariableProxy();
    2824             :     BuildVariableLoadForAccumulatorValue(
    2825             :         proxy->var(), proxy->VariableFeedbackSlot(), proxy->hole_check_mode(),
    2826      198761 :         INSIDE_TYPEOF);
    2827             :   } else {
    2828       13859 :     VisitForAccumulatorValue(expr);
    2829             :   }
    2830      212620 : }
    2831             : 
    2832      103136 : void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
    2833       51568 :   VisitForTypeOfValue(expr->expression());
    2834       51568 :   builder()->TypeOf();
    2835           0 : }
    2836             : 
    2837     1330314 : void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
    2838      417417 :   if (execution_result()->IsEffect()) {
    2839          73 :     VisitForEffect(expr->expression());
    2840      417344 :   } else if (execution_result()->IsTest()) {
    2841      678562 :     TestResultScope* test_result = execution_result()->AsTest();
    2842             :     // No actual logical negation happening, we just swap the control flow by
    2843             :     // swapping the target labels and the fallthrough branch.
    2844             :     VisitForTest(expr->expression(), test_result->else_labels(),
    2845             :                  test_result->then_labels(),
    2846      339281 :                  test_result->inverted_fallthrough());
    2847             :     test_result->SetResultConsumedByTest();
    2848             :   } else {
    2849       78063 :     TypeHint type_hint = VisitForAccumulatorValue(expr->expression());
    2850       78063 :     builder()->LogicalNot(ToBooleanModeFromTypeHint(type_hint));
    2851             :   }
    2852             :   // Always returns a boolean value.
    2853             :   execution_result()->SetResultIsBoolean();
    2854      417417 : }
    2855             : 
    2856      506179 : void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
    2857      506179 :   switch (expr->op()) {
    2858             :     case Token::Value::NOT:
    2859      417417 :       VisitNot(expr);
    2860      417417 :       break;
    2861             :     case Token::Value::TYPEOF:
    2862             :       VisitTypeOf(expr);
    2863             :       break;
    2864             :     case Token::Value::VOID:
    2865             :       VisitVoid(expr);
    2866             :       break;
    2867             :     case Token::Value::DELETE:
    2868       10055 :       VisitDelete(expr);
    2869       10055 :       break;
    2870             :     case Token::Value::BIT_NOT:
    2871             :     case Token::Value::ADD:
    2872             :     case Token::Value::SUB:
    2873             :       // These operators are converted to an equivalent binary operators in
    2874             :       // the parser. These operators are not expected to be visited here.
    2875           0 :       UNREACHABLE();
    2876             :     default:
    2877           0 :       UNREACHABLE();
    2878             :   }
    2879      506179 : }
    2880             : 
    2881       31153 : void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
    2882       10055 :   if (expr->expression()->IsProperty()) {
    2883             :     // Delete of an object property is allowed both in sloppy
    2884             :     // and strict modes.
    2885       27201 :     Property* property = expr->expression()->AsProperty();
    2886        9067 :     Register object = VisitForRegisterValue(property->obj());
    2887        9067 :     VisitForAccumulatorValue(property->key());
    2888        9067 :     builder()->Delete(object, language_mode());
    2889         988 :   } else if (expr->expression()->IsVariableProxy()) {
    2890             :     // Delete of an unqualified identifier is allowed in sloppy mode but is
    2891             :     // not allowed in strict mode. Deleting 'this' is allowed in both modes.
    2892        1682 :     VariableProxy* proxy = expr->expression()->AsVariableProxy();
    2893        1501 :     Variable* variable = proxy->var();
    2894             :     DCHECK(is_sloppy(language_mode()) || variable->is_this());
    2895         841 :     switch (variable->location()) {
    2896             :       case VariableLocation::UNALLOCATED: {
    2897             :         // Global var, let, const or variables not explicitly declared.
    2898         409 :         Register native_context = register_allocator()->NewRegister();
    2899         409 :         Register global_object = register_allocator()->NewRegister();
    2900             :         builder()
    2901             :             ->LoadContextSlot(execution_context()->reg(),
    2902             :                               Context::NATIVE_CONTEXT_INDEX, 0,
    2903         409 :                               BytecodeArrayBuilder::kImmutableSlot)
    2904         409 :             .StoreAccumulatorInRegister(native_context)
    2905             :             .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0,
    2906         409 :                              BytecodeArrayBuilder::kImmutableSlot)
    2907         409 :             .StoreAccumulatorInRegister(global_object)
    2908         409 :             .LoadLiteral(variable->raw_name())
    2909         409 :             .Delete(global_object, language_mode());
    2910             :         break;
    2911             :       }
    2912             :       case VariableLocation::PARAMETER:
    2913             :       case VariableLocation::LOCAL:
    2914             :       case VariableLocation::CONTEXT: {
    2915             :         // Deleting local var/let/const, context variables, and arguments
    2916             :         // does not have any effect.
    2917         181 :         if (variable->is_this()) {
    2918          42 :           builder()->LoadTrue();
    2919             :         } else {
    2920         139 :           builder()->LoadFalse();
    2921             :         }
    2922             :         break;
    2923             :       }
    2924             :       case VariableLocation::LOOKUP: {
    2925         251 :         Register name_reg = register_allocator()->NewRegister();
    2926             :         builder()
    2927         251 :             ->LoadLiteral(variable->raw_name())
    2928         251 :             .StoreAccumulatorInRegister(name_reg)
    2929         251 :             .CallRuntime(Runtime::kDeleteLookupSlot, name_reg);
    2930             :         break;
    2931             :       }
    2932             :       default:
    2933           0 :         UNREACHABLE();
    2934             :     }
    2935             :   } else {
    2936             :     // Delete of an unresolvable reference returns true.
    2937         147 :     VisitForEffect(expr->expression());
    2938         147 :     builder()->LoadTrue();
    2939             :   }
    2940       10055 : }
    2941             : 
    2942     1034788 : void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
    2943             :   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
    2944             : 
    2945             :   // Left-hand side can only be a property, a global or a variable slot.
    2946      162539 :   Property* property = expr->expression()->AsProperty();
    2947      149147 :   LhsKind assign_type = Property::GetAssignType(property);
    2948             : 
    2949      251759 :   bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
    2950             : 
    2951             :   // Evaluate LHS expression and get old value.
    2952             :   Register object, key, old_value;
    2953             :   RegisterList super_property_args;
    2954             :   const AstRawString* name;
    2955      149147 :   switch (assign_type) {
    2956             :     case VARIABLE: {
    2957      427353 :       VariableProxy* proxy = expr->expression()->AsVariableProxy();
    2958             :       BuildVariableLoadForAccumulatorValue(proxy->var(),
    2959             :                                            proxy->VariableFeedbackSlot(),
    2960      142451 :                                            proxy->hole_check_mode());
    2961      142451 :       break;
    2962             :     }
    2963             :     case NAMED_PROPERTY: {
    2964             :       FeedbackSlot slot = property->PropertyFeedbackSlot();
    2965        5829 :       object = VisitForRegisterValue(property->obj());
    2966       11658 :       name = property->key()->AsLiteral()->AsRawPropertyName();
    2967        5829 :       builder()->LoadNamedProperty(object, name, feedback_index(slot));
    2968             :       break;
    2969             :     }
    2970             :     case KEYED_PROPERTY: {
    2971             :       FeedbackSlot slot = property->PropertyFeedbackSlot();
    2972         702 :       object = VisitForRegisterValue(property->obj());
    2973             :       // Use visit for accumulator here since we need the key in the accumulator
    2974             :       // for the LoadKeyedProperty.
    2975         702 :       key = register_allocator()->NewRegister();
    2976         702 :       VisitForAccumulatorValue(property->key());
    2977         702 :       builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
    2978         702 :           object, feedback_index(slot));
    2979             :       break;
    2980             :     }
    2981             :     case NAMED_SUPER_PROPERTY: {
    2982          55 :       super_property_args = register_allocator()->NewRegisterList(4);
    2983          55 :       RegisterList load_super_args = super_property_args.Truncate(3);
    2984         110 :       SuperPropertyReference* super_property =
    2985          55 :           property->obj()->AsSuperPropertyReference();
    2986          55 :       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
    2987          55 :       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
    2988             :       builder()
    2989         165 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    2990          55 :           .StoreAccumulatorInRegister(load_super_args[2])
    2991          55 :           .CallRuntime(Runtime::kLoadFromSuper, load_super_args);
    2992             :       break;
    2993             :     }
    2994             :     case KEYED_SUPER_PROPERTY: {
    2995         110 :       super_property_args = register_allocator()->NewRegisterList(4);
    2996         110 :       RegisterList load_super_args = super_property_args.Truncate(3);
    2997         220 :       SuperPropertyReference* super_property =
    2998         110 :           property->obj()->AsSuperPropertyReference();
    2999         110 :       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
    3000         110 :       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
    3001         110 :       VisitForRegisterValue(property->key(), load_super_args[2]);
    3002         110 :       builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, load_super_args);
    3003             :       break;
    3004             :     }
    3005             :   }
    3006             : 
    3007             :   // Save result for postfix expressions.
    3008             :   FeedbackSlot count_slot = expr->CountBinaryOpFeedbackSlot();
    3009      149147 :   if (is_postfix) {
    3010             :     // Convert old value into a number before saving it.
    3011       25343 :     old_value = register_allocator()->NewRegister();
    3012             :     // TODO(ignition): Think about adding proper PostInc/PostDec bytecodes
    3013             :     // instead of this ToNumber + Inc/Dec dance.
    3014             :     builder()
    3015       25343 :         ->ConvertAccumulatorToNumber(old_value, feedback_index(count_slot))
    3016       25343 :         .LoadAccumulatorWithRegister(old_value);
    3017             :   }
    3018             : 
    3019             :   // Perform +1/-1 operation.
    3020      149147 :   builder()->CountOperation(expr->binary_op(), feedback_index(count_slot));
    3021             : 
    3022             :   // Store the value.
    3023             :   builder()->SetExpressionPosition(expr);
    3024             :   FeedbackSlot feedback_slot = expr->CountSlot();
    3025      149147 :   switch (assign_type) {
    3026             :     case VARIABLE: {
    3027      427353 :       VariableProxy* proxy = expr->expression()->AsVariableProxy();
    3028             :       BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot,
    3029      142451 :                               proxy->hole_check_mode());
    3030      142451 :       break;
    3031             :     }
    3032             :     case NAMED_PROPERTY: {
    3033             :       builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot),
    3034        5829 :                                     language_mode());
    3035        5829 :       break;
    3036             :     }
    3037             :     case KEYED_PROPERTY: {
    3038             :       builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot),
    3039         702 :                                     language_mode());
    3040         702 :       break;
    3041             :     }
    3042             :     case NAMED_SUPER_PROPERTY: {
    3043             :       builder()
    3044          55 :           ->StoreAccumulatorInRegister(super_property_args[3])
    3045          55 :           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
    3046          55 :       break;
    3047             :     }
    3048             :     case KEYED_SUPER_PROPERTY: {
    3049             :       builder()
    3050         110 :           ->StoreAccumulatorInRegister(super_property_args[3])
    3051         110 :           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
    3052         110 :       break;
    3053             :     }
    3054             :   }
    3055             : 
    3056             :   // Restore old value for postfix expressions.
    3057      149147 :   if (is_postfix) {
    3058       25343 :     builder()->LoadAccumulatorWithRegister(old_value);
    3059             :   }
    3060      149147 : }
    3061             : 
    3062     1412369 : void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
    3063     1412369 :   switch (binop->op()) {
    3064             :     case Token::COMMA:
    3065      174809 :       VisitCommaExpression(binop);
    3066      174809 :       break;
    3067             :     case Token::OR:
    3068      158356 :       VisitLogicalOrExpression(binop);
    3069      158356 :       break;
    3070             :     case Token::AND:
    3071      147821 :       VisitLogicalAndExpression(binop);
    3072      147821 :       break;
    3073             :     default:
    3074      931383 :       VisitArithmeticExpression(binop);
    3075      931383 :       break;
    3076             :   }
    3077     1412369 : }
    3078             : 
    3079      363762 : void BytecodeGenerator::BuildLiteralCompareNil(Token::Value op, NilValue nil) {
    3080      181881 :   if (execution_result()->IsTest()) {
    3081      341186 :     TestResultScope* test_result = execution_result()->AsTest();
    3082      170593 :     switch (test_result->fallthrough()) {
    3083             :       case TestFallthrough::kThen:
    3084      106491 :         builder()->JumpIfNotNil(test_result->NewElseLabel(), op, nil);
    3085      106491 :         break;
    3086             :       case TestFallthrough::kElse:
    3087       64102 :         builder()->JumpIfNil(test_result->NewThenLabel(), op, nil);
    3088       64102 :         break;
    3089             :       case TestFallthrough::kNone:
    3090             :         builder()
    3091           0 :             ->JumpIfNil(test_result->NewThenLabel(), op, nil)
    3092           0 :             .Jump(test_result->NewElseLabel());
    3093             :     }
    3094             :     test_result->SetResultConsumedByTest();
    3095             :   } else {
    3096       11288 :     builder()->CompareNil(op, nil);
    3097             :   }
    3098      181881 : }
    3099             : 
    3100     6745908 : void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
    3101             :   Expression* sub_expr;
    3102             :   Literal* literal;
    3103     1211787 :   if (expr->IsLiteralCompareTypeof(&sub_expr, &literal)) {
    3104             :     // Emit a fast literal comparion for expressions of the form:
    3105             :     // typeof(x) === 'string'.
    3106      161052 :     VisitForTypeOfValue(sub_expr);
    3107             :     builder()->SetExpressionPosition(expr);
    3108             :     TestTypeOfFlags::LiteralFlag literal_flag =
    3109      322104 :         TestTypeOfFlags::GetFlagForLiteral(ast_string_constants(), literal);
    3110      161052 :     if (literal_flag == TestTypeOfFlags::LiteralFlag::kOther) {
    3111         184 :       builder()->LoadFalse();
    3112             :     } else {
    3113      160868 :       builder()->CompareTypeOf(literal_flag);
    3114             :     }
    3115     1050735 :   } else if (expr->IsLiteralCompareUndefined(&sub_expr)) {
    3116      105831 :     VisitForAccumulatorValue(sub_expr);
    3117             :     builder()->SetExpressionPosition(expr);
    3118      105831 :     BuildLiteralCompareNil(expr->op(), kUndefinedValue);
    3119      944904 :   } else if (expr->IsLiteralCompareNull(&sub_expr)) {
    3120       76050 :     VisitForAccumulatorValue(sub_expr);
    3121             :     builder()->SetExpressionPosition(expr);
    3122       76050 :     BuildLiteralCompareNil(expr->op(), kNullValue);
    3123             :   } else {
    3124      868854 :     Register lhs = VisitForRegisterValue(expr->left());
    3125      868854 :     VisitForAccumulatorValue(expr->right());
    3126             :     builder()->SetExpressionPosition(expr);
    3127             :     FeedbackSlot slot = expr->CompareOperationFeedbackSlot();
    3128      868854 :     if (slot.IsInvalid()) {
    3129       28741 :       builder()->CompareOperation(expr->op(), lhs);
    3130             :     } else {
    3131      840113 :       builder()->CompareOperation(expr->op(), lhs, feedback_index(slot));
    3132             :     }
    3133             :   }
    3134             :   // Always returns a boolean value.
    3135             :   execution_result()->SetResultIsBoolean();
    3136     1211787 : }
    3137             : 
    3138     4041831 : void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
    3139             :   // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for
    3140             :   // +x and -x by the parser.
    3141             :   FeedbackSlot slot = expr->BinaryOperationFeedbackSlot();
    3142             :   Expression* subexpr;
    3143             :   Smi* literal;
    3144      931383 :   if (expr->IsSmiLiteralOperation(&subexpr, &literal)) {
    3145      307542 :     VisitForAccumulatorValue(subexpr);
    3146             :     builder()->SetExpressionPosition(expr);
    3147             :     builder()->BinaryOperationSmiLiteral(expr->op(), literal,
    3148      615084 :                                          feedback_index(slot));
    3149             :   } else {
    3150      623841 :     Register lhs = VisitForRegisterValue(expr->left());
    3151      623841 :     VisitForAccumulatorValue(expr->right());
    3152             :     builder()->SetExpressionPosition(expr);
    3153      623841 :     builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
    3154             :   }
    3155      931383 : }
    3156             : 
    3157        5043 : void BytecodeGenerator::VisitSpread(Spread* expr) { Visit(expr->expression()); }
    3158             : 
    3159           0 : void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
    3160           0 :   UNREACHABLE();
    3161             : }
    3162             : 
    3163         540 : void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
    3164         180 :   RegisterList args = register_allocator()->NewRegisterList(2);
    3165         180 :   VisitForRegisterValue(expr->argument(), args[1]);
    3166             :   builder()
    3167         360 :       ->MoveRegister(Register::function_closure(), args[0])
    3168         180 :       .CallRuntime(Runtime::kDynamicImportCall, args);
    3169         180 : }
    3170             : 
    3171      280497 : void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
    3172             :   FeedbackSlot load_slot = expr->IteratorPropertyFeedbackSlot();
    3173             :   FeedbackSlot call_slot = expr->IteratorCallFeedbackSlot();
    3174             : 
    3175       34734 :   RegisterList args = register_allocator()->NewRegisterList(1);
    3176       34734 :   Register method = register_allocator()->NewRegister();
    3177       34734 :   Register obj = args[0];
    3178             : 
    3179       34734 :   VisitForAccumulatorValue(expr->iterable());
    3180             : 
    3181       34734 :   if (expr->hint() == IteratorType::kAsync) {
    3182             :     FeedbackSlot async_load_slot = expr->AsyncIteratorPropertyFeedbackSlot();
    3183             :     FeedbackSlot async_call_slot = expr->AsyncIteratorCallFeedbackSlot();
    3184             : 
    3185             :     // Set method to GetMethod(obj, @@asyncIterator)
    3186         375 :     builder()->StoreAccumulatorInRegister(obj).LoadAsyncIteratorProperty(
    3187         375 :         obj, feedback_index(async_load_slot));
    3188             : 
    3189             :     BytecodeLabel async_iterator_undefined, async_iterator_null, done;
    3190             :     // TODO(ignition): Add a single opcode for JumpIfNullOrUndefined
    3191         375 :     builder()->JumpIfUndefined(&async_iterator_undefined);
    3192         375 :     builder()->JumpIfNull(&async_iterator_null);
    3193             : 
    3194             :     // Let iterator be Call(method, obj)
    3195         375 :     builder()->StoreAccumulatorInRegister(method).CallProperty(
    3196         375 :         method, args, feedback_index(async_call_slot));
    3197             : 
    3198             :     // If Type(iterator) is not Object, throw a TypeError exception.
    3199         375 :     builder()->JumpIfJSReceiver(&done);
    3200         375 :     builder()->CallRuntime(Runtime::kThrowSymbolAsyncIteratorInvalid);
    3201             : 
    3202         375 :     builder()->Bind(&async_iterator_undefined);
    3203         375 :     builder()->Bind(&async_iterator_null);
    3204             :     // If method is undefined,
    3205             :     //     Let syncMethod be GetMethod(obj, @@iterator)
    3206             :     builder()
    3207         375 :         ->LoadIteratorProperty(obj, feedback_index(load_slot))
    3208         375 :         .StoreAccumulatorInRegister(method);
    3209             : 
    3210             :     //     Let syncIterator be Call(syncMethod, obj)
    3211         375 :     builder()->CallProperty(method, args, feedback_index(call_slot));
    3212             : 
    3213             :     // Return CreateAsyncFromSyncIterator(syncIterator)
    3214             :     // alias `method` register as it's no longer used
    3215         375 :     Register sync_iter = method;
    3216         375 :     builder()->StoreAccumulatorInRegister(sync_iter).CallRuntime(
    3217         375 :         Runtime::kInlineCreateAsyncFromSyncIterator, sync_iter);
    3218             : 
    3219         375 :     builder()->Bind(&done);
    3220             :   } else {
    3221             :     // Let method be GetMethod(obj, @@iterator).
    3222             :     builder()
    3223       34359 :         ->StoreAccumulatorInRegister(obj)
    3224       34359 :         .LoadIteratorProperty(obj, feedback_index(load_slot))
    3225       34359 :         .StoreAccumulatorInRegister(method);
    3226             : 
    3227             :     // Let iterator be Call(method, obj).
    3228       34359 :     builder()->CallProperty(method, args, feedback_index(call_slot));
    3229             : 
    3230             :     // If Type(iterator) is not Object, throw a TypeError exception.
    3231             :     BytecodeLabel no_type_error;
    3232       34359 :     builder()->JumpIfJSReceiver(&no_type_error);
    3233       34359 :     builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid);
    3234       34359 :     builder()->Bind(&no_type_error);
    3235             :   }
    3236       34734 : }
    3237             : 
    3238       67765 : void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
    3239      135530 :   builder()->LoadAccumulatorWithRegister(Register::function_closure());
    3240           0 : }
    3241             : 
    3242           0 : void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
    3243             :   // Handled by VisitCall().
    3244           0 :   UNREACHABLE();
    3245             : }
    3246             : 
    3247           0 : void BytecodeGenerator::VisitSuperPropertyReference(
    3248          23 :     SuperPropertyReference* expr) {
    3249          23 :   builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
    3250           0 : }
    3251             : 
    3252      349618 : void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
    3253      174809 :   VisitForEffect(binop->left());
    3254      174809 :   Visit(binop->right());
    3255      174809 : }
    3256             : 
    3257      468491 : void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
    3258             :   Expression* left = binop->left();
    3259             :   Expression* right = binop->right();
    3260             : 
    3261      158356 :   if (execution_result()->IsTest()) {
    3262      233011 :     TestResultScope* test_result = execution_result()->AsTest();
    3263             : 
    3264      118279 :     if (left->ToBooleanIsTrue()) {
    3265        3547 :       builder()->Jump(test_result->NewThenLabel());
    3266      114732 :     } else if (left->ToBooleanIsFalse() && right->ToBooleanIsFalse()) {
    3267           0 :       builder()->Jump(test_result->NewElseLabel());
    3268             :     } else {
    3269             :       BytecodeLabels test_right(zone());
    3270             :       VisitForTest(left, test_result->then_labels(), &test_right,
    3271      114732 :                    TestFallthrough::kElse);
    3272      114732 :       test_right.Bind(builder());
    3273             :       VisitForTest(right, test_result->then_labels(),
    3274      114732 :                    test_result->else_labels(), test_result->fallthrough());
    3275             :     }
    3276             :     test_result->SetResultConsumedByTest();
    3277             :   } else {
    3278       40077 :     if (left->ToBooleanIsTrue()) {
    3279        1388 :       VisitForAccumulatorValue(left);
    3280       38689 :     } else if (left->ToBooleanIsFalse()) {
    3281         127 :       VisitForAccumulatorValue(right);
    3282             :     } else {
    3283             :       BytecodeLabel end_label;
    3284       38562 :       TypeHint type_hint = VisitForAccumulatorValue(left);
    3285       38562 :       builder()->JumpIfTrue(ToBooleanModeFromTypeHint(type_hint), &end_label);
    3286       38562 :       VisitForAccumulatorValue(right);
    3287       38562 :       builder()->Bind(&end_label);
    3288             :     }
    3289             :   }
    3290      158356 : }
    3291             : 
    3292      440405 : void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
    3293             :   Expression* left = binop->left();
    3294             :   Expression* right = binop->right();
    3295             : 
    3296      147821 :   if (execution_result()->IsTest()) {
    3297      154216 :     TestResultScope* test_result = execution_result()->AsTest();
    3298             : 
    3299       77110 :     if (left->ToBooleanIsFalse()) {
    3300           4 :       builder()->Jump(test_result->NewElseLabel());
    3301       77106 :     } else if (left->ToBooleanIsTrue() && right->ToBooleanIsTrue()) {
    3302           0 :       builder()->Jump(test_result->NewThenLabel());
    3303             :     } else {
    3304             :       BytecodeLabels test_right(zone());
    3305             :       VisitForTest(left, &test_right, test_result->else_labels(),
    3306       77106 :                    TestFallthrough::kThen);
    3307       77106 :       test_right.Bind(builder());
    3308             :       VisitForTest(right, test_result->then_labels(),
    3309       77106 :                    test_result->else_labels(), test_result->fallthrough());
    3310             :     }
    3311             :     test_result->SetResultConsumedByTest();
    3312             :   } else {
    3313       70711 :     if (left->ToBooleanIsFalse()) {
    3314         128 :       VisitForAccumulatorValue(left);
    3315       70583 :     } else if (left->ToBooleanIsTrue()) {
    3316        1399 :       VisitForAccumulatorValue(right);
    3317             :     } else {
    3318             :       BytecodeLabel end_label;
    3319       69184 :       TypeHint type_hint = VisitForAccumulatorValue(left);
    3320       69184 :       builder()->JumpIfFalse(ToBooleanModeFromTypeHint(type_hint), &end_label);
    3321       69184 :       VisitForAccumulatorValue(right);
    3322       69184 :       builder()->Bind(&end_label);
    3323             :     }
    3324             :   }
    3325      147821 : }
    3326             : 
    3327        1495 : void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
    3328        1495 :   Visit(expr->expression());
    3329        1495 : }
    3330             : 
    3331      411217 : void BytecodeGenerator::BuildNewLocalActivationContext() {
    3332             :   ValueResultScope value_execution_result(this);
    3333      394081 :   Scope* scope = closure_scope();
    3334             : 
    3335             :   // Create the appropriate context.
    3336      201038 :   if (scope->is_script_scope()) {
    3337        6867 :     RegisterList args = register_allocator()->NewRegisterList(2);
    3338             :     builder()
    3339       13734 :         ->LoadAccumulatorWithRegister(Register::function_closure())
    3340        6867 :         .StoreAccumulatorInRegister(args[0])
    3341        6867 :         .LoadLiteral(scope)
    3342        6867 :         .StoreAccumulatorInRegister(args[1])
    3343        6867 :         .CallRuntime(Runtime::kNewScriptContext, args);
    3344      194171 :   } else if (scope->is_module_scope()) {
    3345             :     // We don't need to do anything for the outer script scope.
    3346             :     DCHECK(scope->outer_scope()->is_script_scope());
    3347             : 
    3348             :     // A JSFunction representing a module is called with the module object as
    3349             :     // its sole argument, which we pass on to PushModuleContext.
    3350        1134 :     RegisterList args = register_allocator()->NewRegisterList(3);
    3351             :     builder()
    3352        2268 :         ->MoveRegister(builder()->Parameter(0), args[0])
    3353        2268 :         .LoadAccumulatorWithRegister(Register::function_closure())
    3354        1134 :         .StoreAccumulatorInRegister(args[1])
    3355        1134 :         .LoadLiteral(scope)
    3356        1134 :         .StoreAccumulatorInRegister(args[2])
    3357        1134 :         .CallRuntime(Runtime::kPushModuleContext, args);
    3358             :   } else {
    3359             :     DCHECK(scope->is_function_scope() || scope->is_eval_scope());
    3360      193037 :     int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
    3361      193037 :     if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) {
    3362      193031 :       switch (scope->scope_type()) {
    3363             :         case EVAL_SCOPE:
    3364       21212 :           builder()->CreateEvalContext(slot_count);
    3365       21212 :           break;
    3366             :         case FUNCTION_SCOPE:
    3367      171819 :           builder()->CreateFunctionContext(slot_count);
    3368      171819 :           break;
    3369             :         default:
    3370           0 :           UNREACHABLE();
    3371             :       }
    3372             :     } else {
    3373           6 :       RegisterList args = register_allocator()->NewRegisterList(2);
    3374             :       builder()
    3375          12 :           ->MoveRegister(Register::function_closure(), args[0])
    3376           6 :           .LoadLiteral(Smi::FromInt(scope->scope_type()))
    3377           6 :           .StoreAccumulatorInRegister(args[1])
    3378           6 :           .CallRuntime(Runtime::kNewFunctionContext, args);
    3379             :     }
    3380             :   }
    3381      201038 : }
    3382             : 
    3383      574538 : void BytecodeGenerator::BuildLocalActivationContextInitialization() {
    3384      298025 :   DeclarationScope* scope = closure_scope();
    3385             : 
    3386      372008 :   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
    3387      127055 :     Variable* variable = scope->receiver();
    3388      127055 :     Register receiver(builder()->Receiver());
    3389             :     // Context variable (at bottom of the context chain).
    3390             :     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
    3391      127055 :     builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
    3392      127055 :         execution_context()->reg(), variable->index(), 0);
    3393             :   }
    3394             : 
    3395             :   // Copy parameters into context if necessary.
    3396             :   int num_parameters = scope->num_parameters();
    3397      314718 :   for (int i = 0; i < num_parameters; i++) {
    3398       59695 :     Variable* variable = scope->parameter(i);
    3399      167665 :     if (!variable->IsContextSlot()) continue;
    3400             : 
    3401       59695 :     Register parameter(builder()->Parameter(i));
    3402             :     // Context variable (at bottom of the context chain).
    3403             :     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
    3404       59695 :     builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
    3405       59695 :         execution_context()->reg(), variable->index(), 0);
    3406             :   }
    3407      201038 : }
    3408             : 
    3409       87900 : void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) {
    3410             :   ValueResultScope value_execution_result(this);
    3411             :   DCHECK(scope->is_block_scope());
    3412             : 
    3413       43950 :   VisitFunctionClosureForContext();
    3414       43950 :   builder()->CreateBlockContext(scope);
    3415       43950 : }
    3416             : 
    3417       12159 : void BytecodeGenerator::BuildNewLocalWithContext(Scope* scope) {
    3418             :   ValueResultScope value_execution_result(this);
    3419             : 
    3420        4053 :   Register extension_object = register_allocator()->NewRegister();
    3421             : 
    3422        4053 :   builder()->ConvertAccumulatorToObject(extension_object);
    3423        4053 :   VisitFunctionClosureForContext();
    3424        4053 :   builder()->CreateWithContext(extension_object, scope);
    3425        4053 : }
    3426             : 
    3427      384798 : void BytecodeGenerator::BuildNewLocalCatchContext(Scope* scope) {
    3428             :   ValueResultScope value_execution_result(this);
    3429             :   DCHECK(scope->catch_variable()->IsContextSlot());
    3430             : 
    3431      128266 :   Register exception = register_allocator()->NewRegister();
    3432      128266 :   builder()->StoreAccumulatorInRegister(exception);
    3433      128266 :   VisitFunctionClosureForContext();
    3434             :   builder()->CreateCatchContext(exception, scope->catch_variable()->raw_name(),
    3435      256532 :                                 scope);
    3436      128266 : }
    3437             : 
    3438        8222 : void BytecodeGenerator::VisitObjectLiteralAccessor(
    3439        3596 :     Register home_object, ObjectLiteralProperty* property, Register value_out) {
    3440        8222 :   if (property == nullptr) {
    3441        3596 :     builder()->LoadNull().StoreAccumulatorInRegister(value_out);
    3442             :   } else {
    3443        4626 :     VisitForRegisterValue(property->value(), value_out);
    3444        4626 :     VisitSetHomeObject(value_out, home_object, property);
    3445             :   }
    3446        8222 : }
    3447             : 
    3448      311873 : void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
    3449      311873 :                                            LiteralProperty* property,
    3450        5148 :                                            int slot_number) {
    3451             :   Expression* expr = property->value();
    3452      311873 :   if (FunctionLiteral::NeedsHomeObject(expr)) {
    3453             :     FeedbackSlot slot = property->GetSlot(slot_number);
    3454             :     builder()
    3455        5148 :         ->LoadAccumulatorWithRegister(home_object)
    3456        5148 :         .StoreHomeObjectProperty(value, feedback_index(slot), language_mode());
    3457             :   }
    3458      311873 : }
    3459             : 
    3460     2262279 : void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
    3461     4154874 :   if (variable == nullptr) return;
    3462             : 
    3463             :   DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
    3464             : 
    3465             :   // Allocate and initialize a new arguments object and assign to the
    3466             :   // {arguments} variable.
    3467             :   CreateArgumentsType type =
    3468       66833 :       is_strict(language_mode()) || !info()->has_simple_parameters()
    3469             :           ? CreateArgumentsType::kUnmappedArguments
    3470      118009 :           : CreateArgumentsType::kMappedArguments;
    3471      118009 :   builder()->CreateArguments(type);
    3472             :   BuildVariableAssignment(variable, Token::ASSIGN, FeedbackSlot::Invalid(),
    3473      118009 :                           HoleCheckMode::kElided);
    3474             : }
    3475             : 
    3476     2081753 : void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
    3477     4154872 :   if (rest == nullptr) return;
    3478             : 
    3479             :   // Allocate and initialize a new rest parameter and assign to the {rest}
    3480             :   // variable.
    3481        4317 :   builder()->CreateArguments(CreateArgumentsType::kRestParameter);
    3482             :   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
    3483             :   BuildVariableAssignment(rest, Token::ASSIGN, FeedbackSlot::Invalid(),
    3484        4317 :                           HoleCheckMode::kElided);
    3485             : }
    3486             : 
    3487     2086793 : void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
    3488     4154892 :   if (variable == nullptr) return;
    3489             : 
    3490             :   // Store the closure we were called with in the given variable.
    3491       18694 :   builder()->LoadAccumulatorWithRegister(Register::function_closure());
    3492             :   BuildVariableAssignment(variable, Token::INIT, FeedbackSlot::Invalid(),
    3493        9347 :                           HoleCheckMode::kElided);
    3494             : }
    3495             : 
    3496     2346400 : void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
    3497     4020405 :   if (variable == nullptr) return;
    3498             : 
    3499             :   // Store the new target we were called with in the given variable.
    3500      268958 :   builder()->LoadAccumulatorWithRegister(Register::new_target());
    3501             :   BuildVariableAssignment(variable, Token::INIT, FeedbackSlot::Invalid(),
    3502      134479 :                           HoleCheckMode::kElided);
    3503             : 
    3504             :   // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
    3505             :   // and we need to make sure {BytecodeRegisterOptimizer} flushes its state
    3506             :   // before a local variable containing the <new.target> is used. Using a label
    3507             :   // as below flushes the entire pipeline, we should be more specific here.
    3508             :   BytecodeLabel flush_state_label;
    3509      134479 :   builder()->Bind(&flush_state_label);
    3510             : }
    3511             : 
    3512      528807 : void BytecodeGenerator::VisitFunctionClosureForContext() {
    3513             :   ValueResultScope value_execution_result(this);
    3514      176269 :   if (closure_scope()->is_script_scope()) {
    3515             :     // Contexts nested in the native context have a canonical empty function as
    3516             :     // their closure, not the anonymous closure containing the global code.
    3517       26088 :     Register native_context = register_allocator()->NewRegister();
    3518             :     builder()
    3519             :         ->LoadContextSlot(execution_context()->reg(),
    3520             :                           Context::NATIVE_CONTEXT_INDEX, 0,
    3521       26088 :                           BytecodeArrayBuilder::kImmutableSlot)
    3522       26088 :         .StoreAccumulatorInRegister(native_context)
    3523             :         .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0,
    3524       26088 :                          BytecodeArrayBuilder::kImmutableSlot);
    3525      150181 :   } else if (closure_scope()->is_eval_scope()) {
    3526             :     // Contexts created by a call to eval have the same closure as the
    3527             :     // context calling eval, not the anonymous closure containing the eval
    3528             :     // code. Fetch it from the context.
    3529             :     builder()->LoadContextSlot(execution_context()->reg(),
    3530             :                                Context::CLOSURE_INDEX, 0,
    3531       34024 :                                BytecodeArrayBuilder::kImmutableSlot);
    3532             :   } else {
    3533             :     DCHECK(closure_scope()->is_function_scope() ||
    3534             :            closure_scope()->is_module_scope());
    3535      232314 :     builder()->LoadAccumulatorWithRegister(Register::function_closure());
    3536             :   }
    3537      176269 : }
    3538             : 
    3539             : // Visits the expression |expr| and places the result in the accumulator.
    3540    19321045 : BytecodeGenerator::TypeHint BytecodeGenerator::VisitForAccumulatorValue(
    3541             :     Expression* expr) {
    3542             :   ValueResultScope accumulator_scope(this);
    3543    19321045 :   Visit(expr);
    3544    38642114 :   return accumulator_scope.type_hint();
    3545             : }
    3546             : 
    3547       76252 : void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
    3548       41550 :   if (expr == nullptr) {
    3549       34702 :     builder()->LoadTheHole();
    3550             :   } else {
    3551        6848 :     VisitForAccumulatorValue(expr);
    3552             :   }
    3553       41550 : }
    3554             : 
    3555             : // Visits the expression |expr| and discards the result.
    3556     9526920 : void BytecodeGenerator::VisitForEffect(Expression* expr) {
    3557             :   EffectResultScope effect_scope(this);
    3558     9526920 :   Visit(expr);
    3559     9526931 : }
    3560             : 
    3561             : // Visits the expression |expr| and returns the register containing
    3562             : // the expression result.
    3563    12894523 : Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
    3564     6447262 :   VisitForAccumulatorValue(expr);
    3565     6447262 :   Register result = register_allocator()->NewRegister();
    3566     6447261 :   builder()->StoreAccumulatorInRegister(result);
    3567     6447262 :   return result;
    3568             : }
    3569             : 
    3570             : // Visits the expression |expr| and stores the expression result in
    3571             : // |destination|.
    3572     1407284 : void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
    3573     1407292 :                                               Register destination) {
    3574             :   ValueResultScope register_scope(this);
    3575     1407284 :   Visit(expr);
    3576     1407292 :   builder()->StoreAccumulatorInRegister(destination);
    3577     1407292 : }
    3578             : 
    3579             : // Visits the expression |expr| and pushes the result into a new register
    3580             : // added to the end of |reg_list|.
    3581     8881124 : void BytecodeGenerator::VisitAndPushIntoRegisterList(Expression* expr,
    3582     8881123 :                                                      RegisterList* reg_list) {
    3583             :   {
    3584             :     ValueResultScope register_scope(this);
    3585     8881124 :     Visit(expr);
    3586             :   }
    3587             :   // Grow the register list after visiting the expression to avoid reserving
    3588             :   // the register across the expression evaluation, which could cause memory
    3589             :   // leaks for deep expressions due to dead objects being kept alive by pointers
    3590             :   // in registers.
    3591     8881125 :   Register destination = register_allocator()->GrowRegisterList(reg_list);
    3592     8881123 :   builder()->StoreAccumulatorInRegister(destination);
    3593     8881125 : }
    3594             : 
    3595      126564 : void BytecodeGenerator::BuildPushUndefinedIntoRegisterList(
    3596      126564 :     RegisterList* reg_list) {
    3597      126564 :   Register reg = register_allocator()->GrowRegisterList(reg_list);
    3598      126564 :   builder()->LoadUndefined().StoreAccumulatorInRegister(reg);
    3599      126564 : }
    3600             : 
    3601      612796 : void BytecodeGenerator::BuildLoadPropertyKey(LiteralProperty* property,
    3602        9324 :                                              Register out_reg) {
    3603      306398 :   if (property->key()->IsStringLiteral()) {
    3604      297074 :     VisitForRegisterValue(property->key(), out_reg);
    3605             :   } else {
    3606        9324 :     VisitForAccumulatorValue(property->key());
    3607        9324 :     builder()->ConvertAccumulatorToName(out_reg);
    3608             :   }
    3609      306398 : }
    3610             : 
    3611             : // Visits the expression |expr| for testing its boolean value and jumping to the
    3612             : // |then| or |other| label depending on value and short-circuit semantics
    3613     2052813 : void BytecodeGenerator::VisitForTest(Expression* expr,
    3614             :                                      BytecodeLabels* then_labels,
    3615             :                                      BytecodeLabels* else_labels,
    3616     1347550 :                                      TestFallthrough fallthrough) {
    3617             :   bool result_consumed;
    3618             :   TypeHint type_hint;
    3619             :   {
    3620             :     // To make sure that all temporary registers are returned before generating
    3621             :     // jumps below, we ensure that the result scope is deleted before doing so.
    3622             :     // Dead registers might be materialized otherwise.
    3623             :     TestResultScope test_result(this, then_labels, else_labels, fallthrough);
    3624     2052813 :     Visit(expr);
    3625     2052812 :     result_consumed = test_result.result_consumed_by_test();
    3626     2052812 :     type_hint = test_result.type_hint();
    3627             :   }
    3628     2052812 :   if (!result_consumed) {
    3629             :     ToBooleanMode mode(ToBooleanModeFromTypeHint(type_hint));
    3630     1347550 :     switch (fallthrough) {
    3631             :       case TestFallthrough::kThen:
    3632     1969870 :         builder()->JumpIfFalse(mode, else_labels->New());
    3633      984935 :         break;
    3634             :       case TestFallthrough::kElse:
    3635      725230 :         builder()->JumpIfTrue(mode, then_labels->New());
    3636      362615 :         break;
    3637             :       case TestFallthrough::kNone:
    3638           0 :         builder()->JumpIfTrue(mode, then_labels->New());
    3639           0 :         builder()->Jump(else_labels->New());
    3640             :     }
    3641             :   }
    3642     2052812 : }
    3643             : 
    3644      132319 : void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
    3645             :   DCHECK(scope->declarations()->is_empty());
    3646             :   CurrentScope current_scope(this, scope);
    3647      264638 :   ContextScope context_scope(this, scope);
    3648      132319 :   Visit(stmt);
    3649      132319 : }
    3650             : 
    3651             : BytecodeArrayBuilder::ToBooleanMode
    3652           0 : BytecodeGenerator::ToBooleanModeFromTypeHint(TypeHint type_hint) {
    3653             :   return type_hint == TypeHint::kBoolean ? ToBooleanMode::kAlreadyBoolean
    3654     1565182 :                                          : ToBooleanMode::kConvertToBoolean;
    3655             : }
    3656             : 
    3657     2812290 : LanguageMode BytecodeGenerator::language_mode() const {
    3658             :   return current_scope()->language_mode();
    3659             : }
    3660             : 
    3661           0 : int BytecodeGenerator::feedback_index(FeedbackSlot slot) const {
    3662           0 :   return FeedbackVector::GetIndex(slot);
    3663             : }
    3664             : 
    3665             : Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
    3666             :   return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
    3667         321 :                                     : Runtime::kStoreToSuper_Sloppy;
    3668             : }
    3669             : 
    3670             : Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
    3671             :   return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
    3672         519 :                                     : Runtime::kStoreKeyedToSuper_Sloppy;
    3673             : }
    3674             : 
    3675             : }  // namespace interpreter
    3676             : }  // namespace internal
    3677             : }  // namespace v8

Generated by: LCOV version 1.10