LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-generator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1807 1852 97.6 %
Date: 2017-10-20 Functions: 138 171 80.7 %

          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/ast-source-ranges.h"
       8             : #include "src/ast/compile-time-value.h"
       9             : #include "src/ast/scopes.h"
      10             : #include "src/builtins/builtins-constructor.h"
      11             : #include "src/code-stubs.h"
      12             : #include "src/compilation-info.h"
      13             : #include "src/compiler.h"
      14             : #include "src/interpreter/bytecode-flags.h"
      15             : #include "src/interpreter/bytecode-jump-table.h"
      16             : #include "src/interpreter/bytecode-label.h"
      17             : #include "src/interpreter/bytecode-register-allocator.h"
      18             : #include "src/interpreter/control-flow-builders.h"
      19             : #include "src/objects-inl.h"
      20             : #include "src/objects/debug-objects.h"
      21             : #include "src/parsing/parse-info.h"
      22             : #include "src/parsing/token.h"
      23             : 
      24             : namespace v8 {
      25             : namespace internal {
      26             : namespace interpreter {
      27             : 
      28             : // Scoped class tracking context objects created by the visitor. Represents
      29             : // mutations of the context chain within the function body, allowing pushing and
      30             : // popping of the current {context_register} during visitation.
      31             : class BytecodeGenerator::ContextScope BASE_EMBEDDED {
      32             :  public:
      33     2469053 :   ContextScope(BytecodeGenerator* generator, Scope* scope)
      34             :       : generator_(generator),
      35             :         scope_(scope),
      36     2806786 :         outer_(generator_->execution_context()),
      37             :         register_(Register::current_context()),
      38     4938106 :         depth_(0) {
      39             :     DCHECK(scope->NeedsContext() || outer_ == nullptr);
      40     2469058 :     if (outer_) {
      41      337733 :       depth_ = outer_->depth_ + 1;
      42             : 
      43             :       // Push the outer context into a new context register.
      44             :       Register outer_context_reg =
      45      675466 :           generator_->register_allocator()->NewRegister();
      46      337733 :       outer_->set_register(outer_context_reg);
      47      675466 :       generator_->builder()->PushContext(outer_context_reg);
      48             :     }
      49     2469058 :     generator_->set_execution_context(this);
      50     2469058 :   }
      51             : 
      52     2469057 :   ~ContextScope() {
      53     2469057 :     if (outer_) {
      54             :       DCHECK_EQ(register_.index(), Register::current_context().index());
      55      337733 :       generator_->builder()->PopContext(outer_->reg());
      56      337733 :       outer_->set_register(register_);
      57             :     }
      58     2469057 :     generator_->set_execution_context(outer_);
      59     2469057 :   }
      60             : 
      61             :   // Returns the depth of the given |scope| for the current execution context.
      62             :   int ContextChainDepth(Scope* scope) {
      63     4336596 :     return scope_->ContextChainLength(scope);
      64             :   }
      65             : 
      66             :   // Returns the execution context at |depth| in the current context chain if it
      67             :   // is a function local execution context, otherwise returns nullptr.
      68             :   ContextScope* Previous(int depth) {
      69     4296625 :     if (depth > depth_) {
      70             :       return nullptr;
      71             :     }
      72             : 
      73             :     ContextScope* previous = this;
      74       71182 :     for (int i = depth; i > 0; --i) {
      75       71182 :       previous = previous->outer_;
      76             :     }
      77             :     return previous;
      78             :   }
      79             : 
      80             :   Register reg() const { return register_; }
      81             : 
      82             :  private:
      83             :   const BytecodeArrayBuilder* builder() const { return generator_->builder(); }
      84             : 
      85      675466 :   void set_register(Register reg) { register_ = reg; }
      86             : 
      87             :   BytecodeGenerator* generator_;
      88             :   Scope* scope_;
      89             :   ContextScope* outer_;
      90             :   Register register_;
      91             :   int depth_;
      92             : };
      93             : 
      94             : // Scoped class for tracking control statements entered by the
      95             : // visitor. The pattern derives AstGraphBuilder::ControlScope.
      96             : class BytecodeGenerator::ControlScope BASE_EMBEDDED {
      97             :  public:
      98    15312392 :   explicit ControlScope(BytecodeGenerator* generator)
      99             :       : generator_(generator), outer_(generator->execution_control()),
     100    22968588 :         context_(generator->execution_context()) {
     101             :     generator_->set_execution_control(this);
     102             :   }
     103     7656196 :   virtual ~ControlScope() { generator_->set_execution_control(outer()); }
     104             : 
     105             :   void Break(Statement* stmt) {
     106       67991 :     PerformCommand(CMD_BREAK, stmt, kNoSourcePosition);
     107             :   }
     108             :   void Continue(Statement* stmt) {
     109        8726 :     PerformCommand(CMD_CONTINUE, stmt, kNoSourcePosition);
     110             :   }
     111             :   void ReturnAccumulator(int source_position = kNoSourcePosition) {
     112     2177983 :     PerformCommand(CMD_RETURN, nullptr, source_position);
     113             :   }
     114             :   void AsyncReturnAccumulator(int source_position = kNoSourcePosition) {
     115        3830 :     PerformCommand(CMD_ASYNC_RETURN, nullptr, source_position);
     116             :   }
     117             : 
     118             :   class DeferredCommands;
     119             : 
     120             :  protected:
     121             :   enum Command {
     122             :     CMD_BREAK,
     123             :     CMD_CONTINUE,
     124             :     CMD_RETURN,
     125             :     CMD_ASYNC_RETURN,
     126             :     CMD_RETHROW
     127             :   };
     128             :   static constexpr bool CommandUsesAccumulator(Command command) {
     129             :     return command != CMD_BREAK && command != CMD_CONTINUE;
     130             :   }
     131             : 
     132             :   void PerformCommand(Command command, Statement* statement,
     133             :                       int source_position);
     134             :   virtual bool Execute(Command command, Statement* statement,
     135             :                        int source_position) = 0;
     136             : 
     137             :   // Helper to pop the context chain to a depth expected by this control scope.
     138             :   // Note that it is the responsibility of each individual {Execute} method to
     139             :   // trigger this when commands are handled and control-flow continues locally.
     140             :   void PopContextToExpectedDepth();
     141             : 
     142             :   BytecodeGenerator* generator() const { return generator_; }
     143             :   ControlScope* outer() const { return outer_; }
     144             :   ContextScope* context() const { return context_; }
     145             : 
     146             :  private:
     147             :   BytecodeGenerator* generator_;
     148             :   ControlScope* outer_;
     149             :   ContextScope* context_;
     150             : 
     151             :   DISALLOW_COPY_AND_ASSIGN(ControlScope);
     152             : };
     153             : 
     154             : // Helper class for a try-finally control scope. It can record intercepted
     155             : // control-flow commands that cause entry into a finally-block, and re-apply
     156             : // them after again leaving that block. Special tokens are used to identify
     157             : // paths going through the finally-block to dispatch after leaving the block.
     158             : class BytecodeGenerator::ControlScope::DeferredCommands final {
     159             :  public:
     160       36312 :   DeferredCommands(BytecodeGenerator* generator, Register token_register,
     161             :                    Register result_register)
     162             :       : generator_(generator),
     163             :         deferred_(generator->zone()),
     164             :         token_register_(token_register),
     165             :         result_register_(result_register),
     166             :         return_token_(-1),
     167             :         async_return_token_(-1),
     168       72624 :         rethrow_token_(-1) {}
     169             : 
     170             :   // One recorded control-flow command.
     171             :   struct Entry {
     172             :     Command command;       // The command type being applied on this path.
     173             :     Statement* statement;  // The target statement for the command or {nullptr}.
     174             :     int token;             // A token identifying this particular path.
     175             :   };
     176             : 
     177             :   // Records a control-flow command while entering the finally-block. This also
     178             :   // generates a new dispatch token that identifies one particular path. This
     179             :   // expects the result to be in the accumulator.
     180      215376 :   void RecordCommand(Command command, Statement* statement) {
     181       53844 :     int token = GetTokenForCommand(command, statement);
     182             : 
     183             :     DCHECK_LT(token, deferred_.size());
     184             :     DCHECK_EQ(deferred_[token].command, command);
     185             :     DCHECK_EQ(deferred_[token].statement, statement);
     186             :     DCHECK_EQ(deferred_[token].token, token);
     187             : 
     188       53844 :     if (CommandUsesAccumulator(command)) {
     189       53568 :       builder()->StoreAccumulatorInRegister(result_register_);
     190             :     }
     191       53844 :     builder()->LoadLiteral(Smi::FromInt(token));
     192       53844 :     builder()->StoreAccumulatorInRegister(token_register_);
     193       53844 :     if (!CommandUsesAccumulator(command)) {
     194             :       // If we're not saving the accumulator in the result register, shove a
     195             :       // harmless value there instead so that it is still considered "killed" in
     196             :       // the liveness analysis. Normally we would LdaUndefined first, but the
     197             :       // Smi token value is just as good, and by reusing it we save a bytecode.
     198         276 :       builder()->StoreAccumulatorInRegister(result_register_);
     199             :     }
     200       53844 :   }
     201             : 
     202             :   // Records the dispatch token to be used to identify the re-throw path when
     203             :   // the finally-block has been entered through the exception handler. This
     204             :   // expects the exception to be in the accumulator.
     205             :   void RecordHandlerReThrowPath() {
     206             :     // The accumulator contains the exception object.
     207       36312 :     RecordCommand(CMD_RETHROW, nullptr);
     208             :   }
     209             : 
     210             :   // Records the dispatch token to be used to identify the implicit fall-through
     211             :   // path at the end of a try-block into the corresponding finally-block.
     212      108936 :   void RecordFallThroughPath() {
     213       36312 :     builder()->LoadLiteral(Smi::FromInt(-1));
     214       36312 :     builder()->StoreAccumulatorInRegister(token_register_);
     215             :     // Since we're not saving the accumulator in the result register, shove a
     216             :     // harmless value there instead so that it is still considered "killed" in
     217             :     // the liveness analysis. Normally we would LdaUndefined first, but the Smi
     218             :     // token value is just as good, and by reusing it we save a bytecode.
     219       36312 :     builder()->StoreAccumulatorInRegister(result_register_);
     220       36312 :   }
     221             : 
     222             :   // Applies all recorded control-flow commands after the finally-block again.
     223             :   // This generates a dynamic dispatch on the token from the entry point.
     224      239518 :   void ApplyDeferredCommands() {
     225       72624 :     if (deferred_.size() == 0) return;
     226             : 
     227             :     BytecodeLabel fall_through;
     228             : 
     229       36312 :     if (deferred_.size() == 1) {
     230             :       // For a single entry, just jump to the fallthrough if we don't match the
     231             :       // entry token.
     232             :       const Entry& entry = deferred_[0];
     233             : 
     234             :       builder()
     235       52484 :           ->LoadLiteral(Smi::FromInt(entry.token))
     236       26242 :           .CompareOperation(Token::EQ_STRICT, token_register_)
     237       26242 :           .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &fall_through);
     238             : 
     239       26242 :       if (CommandUsesAccumulator(entry.command)) {
     240       26242 :         builder()->LoadAccumulatorWithRegister(result_register_);
     241             :       }
     242             :       execution_control()->PerformCommand(entry.command, entry.statement,
     243       52484 :                                           kNoSourcePosition);
     244             :     } else {
     245             :       // For multiple entries, build a jump table and switch on the token,
     246             :       // jumping to the fallthrough if none of them match.
     247             : 
     248             :       BytecodeJumpTable* jump_table =
     249       20140 :           builder()->AllocateJumpTable(static_cast<int>(deferred_.size()), 0);
     250             :       builder()
     251       10070 :           ->LoadAccumulatorWithRegister(token_register_)
     252       10070 :           .SwitchOnSmiNoFeedback(jump_table)
     253       10070 :           .Jump(&fall_through);
     254       42908 :       for (const Entry& entry : deferred_) {
     255       45536 :         builder()->Bind(jump_table, entry.token);
     256             : 
     257       22768 :         if (CommandUsesAccumulator(entry.command)) {
     258       22492 :           builder()->LoadAccumulatorWithRegister(result_register_);
     259             :         }
     260             :         execution_control()->PerformCommand(entry.command, entry.statement,
     261       45536 :                                             kNoSourcePosition);
     262             :       }
     263             :     }
     264             : 
     265       36312 :     builder()->Bind(&fall_through);
     266             :   }
     267             : 
     268      424664 :   BytecodeArrayBuilder* builder() { return generator_->builder(); }
     269       49010 :   ControlScope* execution_control() { return generator_->execution_control(); }
     270             : 
     271             :  private:
     272       53844 :   int GetTokenForCommand(Command command, Statement* statement) {
     273       53844 :     switch (command) {
     274             :       case CMD_RETURN:
     275       13101 :         return GetReturnToken();
     276             :       case CMD_ASYNC_RETURN:
     277        4074 :         return GetAsyncReturnToken();
     278             :       case CMD_RETHROW:
     279       36393 :         return GetRethrowToken();
     280             :       default:
     281             :         // TODO(leszeks): We could also search for entries with the same
     282             :         // command and statement.
     283         276 :         return GetNewTokenForCommand(command, statement);
     284             :     }
     285             :   }
     286             : 
     287       13101 :   int GetReturnToken() {
     288       13101 :     if (return_token_ == -1) {
     289        9574 :       return_token_ = GetNewTokenForCommand(CMD_RETURN, nullptr);
     290             :     }
     291       13101 :     return return_token_;
     292             :   }
     293             : 
     294        4074 :   int GetAsyncReturnToken() {
     295        4074 :     if (async_return_token_ == -1) {
     296        2848 :       async_return_token_ = GetNewTokenForCommand(CMD_ASYNC_RETURN, nullptr);
     297             :     }
     298        4074 :     return async_return_token_;
     299             :   }
     300             : 
     301       36393 :   int GetRethrowToken() {
     302       36393 :     if (rethrow_token_ == -1) {
     303       36312 :       rethrow_token_ = GetNewTokenForCommand(CMD_RETHROW, nullptr);
     304             :     }
     305       36393 :     return rethrow_token_;
     306             :   }
     307             : 
     308             :   int GetNewTokenForCommand(Command command, Statement* statement) {
     309       98020 :     int token = static_cast<int>(deferred_.size());
     310       98020 :     deferred_.push_back({command, statement, token});
     311             :     return token;
     312             :   }
     313             : 
     314             :   BytecodeGenerator* generator_;
     315             :   ZoneVector<Entry> deferred_;
     316             :   Register token_register_;
     317             :   Register result_register_;
     318             : 
     319             :   // Tokens for commands that don't need a statement.
     320             :   int return_token_;
     321             :   int async_return_token_;
     322             :   int rethrow_token_;
     323             : };
     324             : 
     325             : // Scoped class for dealing with control flow reaching the function level.
     326     2131325 : class BytecodeGenerator::ControlScopeForTopLevel final
     327             :     : public BytecodeGenerator::ControlScope {
     328             :  public:
     329             :   explicit ControlScopeForTopLevel(BytecodeGenerator* generator)
     330     2131325 :       : ControlScope(generator) {}
     331             : 
     332             :  protected:
     333     2208738 :   bool Execute(Command command, Statement* statement,
     334             :                int source_position) override {
     335     2208738 :     switch (command) {
     336             :       case CMD_BREAK:  // We should never see break/continue in top-level.
     337             :       case CMD_CONTINUE:
     338           0 :         UNREACHABLE();
     339             :       case CMD_RETURN:
     340             :         // No need to pop contexts, execution leaves the method body.
     341     2208739 :         generator()->BuildReturn(source_position);
     342     2174456 :         return true;
     343             :       case CMD_ASYNC_RETURN:
     344             :         // No need to pop contexts, execution leaves the method body.
     345        2604 :         generator()->BuildAsyncReturn(source_position);
     346        2604 :         return true;
     347             :       case CMD_RETHROW:
     348             :         // No need to pop contexts, execution leaves the method body.
     349             :         generator()->BuildReThrow();
     350       31681 :         return true;
     351             :     }
     352             :     return false;
     353             :   }
     354             : };
     355             : 
     356             : // Scoped class for enabling break inside blocks and switch blocks.
     357     5163438 : class BytecodeGenerator::ControlScopeForBreakable final
     358             :     : public BytecodeGenerator::ControlScope {
     359             :  public:
     360             :   ControlScopeForBreakable(BytecodeGenerator* generator,
     361             :                            BreakableStatement* statement,
     362             :                            BreakableControlFlowBuilder* control_builder)
     363             :       : ControlScope(generator),
     364             :         statement_(statement),
     365     5163438 :         control_builder_(control_builder) {}
     366             : 
     367             :  protected:
     368      594221 :   bool Execute(Command command, Statement* statement,
     369             :                int source_position) override {
     370      594221 :     control_builder_->set_needs_continuation_counter();
     371      594221 :     if (statement != statement_) return false;
     372       36151 :     switch (command) {
     373             :       case CMD_BREAK:
     374       36151 :         PopContextToExpectedDepth();
     375       36151 :         control_builder_->Break();
     376       36151 :         return true;
     377             :       case CMD_CONTINUE:
     378             :       case CMD_RETURN:
     379             :       case CMD_ASYNC_RETURN:
     380             :       case CMD_RETHROW:
     381             :         break;
     382             :     }
     383             :     return false;
     384             :   }
     385             : 
     386             :  private:
     387             :   Statement* statement_;
     388             :   BreakableControlFlowBuilder* control_builder_;
     389             : };
     390             : 
     391             : // Scoped class for enabling 'break' and 'continue' in iteration
     392             : // constructs, e.g. do...while, while..., for...
     393             : class BytecodeGenerator::ControlScopeForIteration final
     394             :     : public BytecodeGenerator::ControlScope {
     395             :  public:
     396             :   ControlScopeForIteration(BytecodeGenerator* generator,
     397             :                            IterationStatement* statement,
     398             :                            LoopBuilder* loop_builder)
     399             :       : ControlScope(generator),
     400             :         statement_(statement),
     401      222999 :         loop_builder_(loop_builder) {
     402      222999 :     generator->loop_depth_++;
     403             :   }
     404      222999 :   ~ControlScopeForIteration() { generator()->loop_depth_--; }
     405             : 
     406             :  protected:
     407       90846 :   bool Execute(Command command, Statement* statement,
     408             :                int source_position) override {
     409       90846 :     if (statement != statement_) return false;
     410       40566 :     switch (command) {
     411             :       case CMD_BREAK:
     412       31840 :         PopContextToExpectedDepth();
     413       31840 :         loop_builder_->Break();
     414       31840 :         return true;
     415             :       case CMD_CONTINUE:
     416        8726 :         PopContextToExpectedDepth();
     417        8726 :         loop_builder_->Continue();
     418        8726 :         return true;
     419             :       case CMD_RETURN:
     420             :       case CMD_ASYNC_RETURN:
     421             :       case CMD_RETHROW:
     422             :         break;
     423             :     }
     424             :     return false;
     425             :   }
     426             : 
     427             :  private:
     428             :   Statement* statement_;
     429             :   LoopBuilder* loop_builder_;
     430             : };
     431             : 
     432             : // Scoped class for enabling 'throw' in try-catch constructs.
     433      102122 : class BytecodeGenerator::ControlScopeForTryCatch final
     434             :     : public BytecodeGenerator::ControlScope {
     435             :  public:
     436             :   ControlScopeForTryCatch(BytecodeGenerator* generator,
     437             :                           TryCatchBuilder* try_catch_builder)
     438      102122 :       : ControlScope(generator) {}
     439             : 
     440             :  protected:
     441       32747 :   bool Execute(Command command, Statement* statement,
     442             :                int source_position) override {
     443       32747 :     switch (command) {
     444             :       case CMD_BREAK:
     445             :       case CMD_CONTINUE:
     446             :       case CMD_RETURN:
     447             :       case CMD_ASYNC_RETURN:
     448             :         break;
     449             :       case CMD_RETHROW:
     450             :         // No need to pop contexts, execution re-enters the method body via the
     451             :         // stack unwinding mechanism which itself restores contexts correctly.
     452        4550 :         generator()->BuildReThrow();
     453        4550 :         return true;
     454             :     }
     455             :     return false;
     456             :   }
     457             : };
     458             : 
     459             : // Scoped class for enabling control flow through try-finally constructs.
     460       36312 : class BytecodeGenerator::ControlScopeForTryFinally final
     461             :     : public BytecodeGenerator::ControlScope {
     462             :  public:
     463             :   ControlScopeForTryFinally(BytecodeGenerator* generator,
     464             :                             TryFinallyBuilder* try_finally_builder,
     465             :                             DeferredCommands* commands)
     466             :       : ControlScope(generator),
     467             :         try_finally_builder_(try_finally_builder),
     468       36312 :         commands_(commands) {}
     469             : 
     470             :  protected:
     471       17532 :   bool Execute(Command command, Statement* statement,
     472             :                int source_position) override {
     473       17532 :     switch (command) {
     474             :       case CMD_BREAK:
     475             :       case CMD_CONTINUE:
     476             :       case CMD_RETURN:
     477             :       case CMD_ASYNC_RETURN:
     478             :       case CMD_RETHROW:
     479       17532 :         PopContextToExpectedDepth();
     480             :         // We don't record source_position here since we don't generate return
     481             :         // bytecode right here and will generate it later as part of finally
     482             :         // block. Each return bytecode generated in finally block will get own
     483             :         // return source position from corresponded return statement or we'll
     484             :         // use end of function if no return statement is presented.
     485       17532 :         commands_->RecordCommand(command, statement);
     486       17532 :         try_finally_builder_->LeaveTry();
     487       17532 :         return true;
     488             :     }
     489             :     return false;
     490             :   }
     491             : 
     492             :  private:
     493             :   TryFinallyBuilder* try_finally_builder_;
     494             :   DeferredCommands* commands_;
     495             : };
     496             : 
     497     2307539 : void BytecodeGenerator::ControlScope::PerformCommand(Command command,
     498             :                                                      Statement* statement,
     499             :                                                      int source_position) {
     500      636547 :   ControlScope* current = this;
     501      636547 :   do {
     502     2944086 :     if (current->Execute(command, statement, source_position)) {
     503     2307540 :       return;
     504             :     }
     505             :     current = current->outer();
     506             :   } while (current != nullptr);
     507           0 :   UNREACHABLE();
     508             : }
     509             : 
     510      188498 : void BytecodeGenerator::ControlScope::PopContextToExpectedDepth() {
     511             :   // Pop context to the expected depth. Note that this can in fact pop multiple
     512             :   // contexts at once because the {PopContext} bytecode takes a saved register.
     513      188498 :   if (generator()->execution_context() != context()) {
     514       16294 :     generator()->builder()->PopContext(context()->reg());
     515             :   }
     516       94249 : }
     517             : 
     518             : class BytecodeGenerator::RegisterAllocationScope final {
     519             :  public:
     520             :   explicit RegisterAllocationScope(BytecodeGenerator* generator)
     521             :       : generator_(generator),
     522             :         outer_next_register_index_(
     523   149152268 :             generator->register_allocator()->next_register_index()) {}
     524             : 
     525    74576017 :   ~RegisterAllocationScope() {
     526             :     generator_->register_allocator()->ReleaseRegisters(
     527    74576017 :         outer_next_register_index_);
     528    74576009 :   }
     529             : 
     530             :  private:
     531             :   BytecodeGenerator* generator_;
     532             :   int outer_next_register_index_;
     533             : 
     534             :   DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
     535             : };
     536             : 
     537             : // Scoped base class for determining how the result of an expression will be
     538             : // used.
     539             : class BytecodeGenerator::ExpressionResultScope {
     540             :  public:
     541    42382378 :   ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
     542             :       : generator_(generator),
     543             :         outer_(generator->execution_result()),
     544             :         allocator_(generator),
     545             :         kind_(kind),
     546   127147134 :         type_hint_(TypeHint::kAny) {
     547             :     generator_->set_execution_result(this);
     548             :   }
     549             : 
     550    84764786 :   virtual ~ExpressionResultScope() {
     551    42382393 :     generator_->set_execution_result(outer_);
     552           0 :   }
     553             : 
     554             :   bool IsEffect() const { return kind_ == Expression::kEffect; }
     555             :   bool IsValue() const { return kind_ == Expression::kValue; }
     556             :   bool IsTest() const { return kind_ == Expression::kTest; }
     557             : 
     558             :   TestResultScope* AsTest() {
     559             :     DCHECK(IsTest());
     560             :     return reinterpret_cast<TestResultScope*>(this);
     561             :   }
     562             : 
     563             :   // Specify expression always returns a Boolean result value.
     564             :   void SetResultIsBoolean() {
     565             :     DCHECK_EQ(type_hint_, TypeHint::kAny);
     566     1554144 :     type_hint_ = TypeHint::kBoolean;
     567             :   }
     568             : 
     569             :   TypeHint type_hint() const { return type_hint_; }
     570             : 
     571             :  private:
     572             :   BytecodeGenerator* generator_;
     573             :   ExpressionResultScope* outer_;
     574             :   RegisterAllocationScope allocator_;
     575             :   Expression::Context kind_;
     576             :   TypeHint type_hint_;
     577             : 
     578             :   DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
     579             : };
     580             : 
     581             : // Scoped class used when the result of the current expression is not
     582             : // expected to produce a result.
     583     9541610 : class BytecodeGenerator::EffectResultScope final
     584             :     : public ExpressionResultScope {
     585             :  public:
     586             :   explicit EffectResultScope(BytecodeGenerator* generator)
     587     9541607 :       : ExpressionResultScope(generator, Expression::kEffect) {}
     588             : };
     589             : 
     590             : // Scoped class used when the result of the current expression to be
     591             : // evaluated should go into the interpreter's accumulator.
     592    33027719 : class BytecodeGenerator::ValueResultScope final : public ExpressionResultScope {
     593             :  public:
     594     1543406 :   explicit ValueResultScope(BytecodeGenerator* generator)
     595    33027704 :       : ExpressionResultScope(generator, Expression::kValue) {}
     596             : };
     597             : 
     598             : // Scoped class used when the result of the current expression to be
     599             : // evaluated is only tested with jumps to two branches.
     600     1356472 : class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
     601             :  public:
     602             :   TestResultScope(BytecodeGenerator* generator, BytecodeLabels* then_labels,
     603             :                   BytecodeLabels* else_labels, TestFallthrough fallthrough)
     604             :       : ExpressionResultScope(generator, Expression::kTest),
     605             :         result_consumed_by_test_(false),
     606             :         fallthrough_(fallthrough),
     607             :         then_labels_(then_labels),
     608     1356473 :         else_labels_(else_labels) {}
     609             : 
     610             :   // Used when code special cases for TestResultScope and consumes any
     611             :   // possible value by testing and jumping to a then/else label.
     612             :   void SetResultConsumedByTest() {
     613      640399 :     result_consumed_by_test_ = true;
     614             :   }
     615             :   bool result_consumed_by_test() { return result_consumed_by_test_; }
     616             : 
     617             :   // Inverts the control flow of the operation, swapping the then and else
     618             :   // labels and the fallthrough.
     619      283388 :   void InvertControlFlow() {
     620             :     std::swap(then_labels_, else_labels_);
     621      283388 :     fallthrough_ = inverted_fallthrough();
     622             :   }
     623             : 
     624       48364 :   BytecodeLabel* NewThenLabel() { return then_labels_->New(); }
     625       78572 :   BytecodeLabel* NewElseLabel() { return else_labels_->New(); }
     626             : 
     627             :   BytecodeLabels* then_labels() const { return then_labels_; }
     628             :   BytecodeLabels* else_labels() const { return else_labels_; }
     629             : 
     630             :   void set_then_labels(BytecodeLabels* then_labels) {
     631       68068 :     then_labels_ = then_labels;
     632             :   }
     633             :   void set_else_labels(BytecodeLabels* else_labels) {
     634      110283 :     else_labels_ = else_labels;
     635             :   }
     636             : 
     637             :   TestFallthrough fallthrough() const { return fallthrough_; }
     638             :   TestFallthrough inverted_fallthrough() const {
     639      283388 :     switch (fallthrough_) {
     640             :       case TestFallthrough::kThen:
     641             :         return TestFallthrough::kElse;
     642             :       case TestFallthrough::kElse:
     643             :         return TestFallthrough::kThen;
     644             :       default:
     645             :         return TestFallthrough::kNone;
     646             :     }
     647             :   }
     648             :   void set_fallthrough(TestFallthrough fallthrough) {
     649      178351 :     fallthrough_ = fallthrough;
     650             :   }
     651             : 
     652             :  private:
     653             :   bool result_consumed_by_test_;
     654             :   TestFallthrough fallthrough_;
     655             :   BytecodeLabels* then_labels_;
     656             :   BytecodeLabels* else_labels_;
     657             : 
     658             :   DISALLOW_COPY_AND_ASSIGN(TestResultScope);
     659             : };
     660             : 
     661             : // Used to build a list of global declaration initial value pairs.
     662             : class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
     663             :  public:
     664     2220196 :   explicit GlobalDeclarationsBuilder(Zone* zone)
     665             :       : declarations_(0, zone),
     666             :         constant_pool_entry_(0),
     667     2220197 :         has_constant_pool_entry_(false) {}
     668             : 
     669             :   void AddFunctionDeclaration(const AstRawString* name, FeedbackSlot slot,
     670             :                               FeedbackSlot literal_slot,
     671             :                               FunctionLiteral* func) {
     672             :     DCHECK(!slot.IsInvalid());
     673      377512 :     declarations_.push_back(Declaration(name, slot, literal_slot, func));
     674             :   }
     675             : 
     676             :   void AddUndefinedDeclaration(const AstRawString* name, FeedbackSlot slot) {
     677             :     DCHECK(!slot.IsInvalid());
     678     1822390 :     declarations_.push_back(Declaration(name, slot, nullptr));
     679             :   }
     680             : 
     681     2188886 :   Handle<FixedArray> AllocateDeclarations(CompilationInfo* info,
     682             :                                           Handle<Script> script) {
     683             :     DCHECK(has_constant_pool_entry_);
     684             :     int array_index = 0;
     685             :     Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray(
     686      266610 :         static_cast<int>(declarations_.size() * 4), TENURED);
     687     1277691 :     for (const Declaration& declaration : declarations_) {
     688     1099951 :       FunctionLiteral* func = declaration.func;
     689             :       Handle<Object> initial_value;
     690     1099951 :       if (func == nullptr) {
     691             :         initial_value = info->isolate()->factory()->undefined_value();
     692             :       } else {
     693             :         initial_value =
     694      188756 :             Compiler::GetSharedFunctionInfo(func, script, info->isolate());
     695             :       }
     696             : 
     697             :       // Return a null handle if any initial values can't be created. Caller
     698             :       // will set stack overflow.
     699     1099951 :       if (initial_value.is_null()) return Handle<FixedArray>();
     700             : 
     701     3299853 :       data->set(array_index++, *declaration.name->string());
     702     1099951 :       data->set(array_index++, Smi::FromInt(declaration.slot.ToInt()));
     703             :       Object* undefined_or_literal_slot;
     704     1099951 :       if (declaration.literal_slot.IsInvalid()) {
     705      911195 :         undefined_or_literal_slot = info->isolate()->heap()->undefined_value();
     706             :       } else {
     707             :         undefined_or_literal_slot =
     708             :             Smi::FromInt(declaration.literal_slot.ToInt());
     709             :       }
     710     2199902 :       data->set(array_index++, undefined_or_literal_slot);
     711     2199902 :       data->set(array_index++, *initial_value);
     712             :     }
     713       88870 :     return data;
     714             :   }
     715             : 
     716             :   size_t constant_pool_entry() {
     717             :     DCHECK(has_constant_pool_entry_);
     718             :     return constant_pool_entry_;
     719             :   }
     720             : 
     721             :   void set_constant_pool_entry(size_t constant_pool_entry) {
     722             :     DCHECK(!empty());
     723             :     DCHECK(!has_constant_pool_entry_);
     724       88870 :     constant_pool_entry_ = constant_pool_entry;
     725       88870 :     has_constant_pool_entry_ = true;
     726             :   }
     727             : 
     728             :   bool empty() { return declarations_.empty(); }
     729             : 
     730             :  private:
     731             :   struct Declaration {
     732     4440392 :     Declaration() : slot(FeedbackSlot::Invalid()), func(nullptr) {}
     733             :     Declaration(const AstRawString* name, FeedbackSlot slot,
     734             :                 FeedbackSlot literal_slot, FunctionLiteral* func)
     735      188756 :         : name(name), slot(slot), literal_slot(literal_slot), func(func) {}
     736             :     Declaration(const AstRawString* name, FeedbackSlot slot,
     737             :                 FunctionLiteral* func)
     738             :         : name(name),
     739             :           slot(slot),
     740             :           literal_slot(FeedbackSlot::Invalid()),
     741      911195 :           func(func) {}
     742             : 
     743             :     const AstRawString* name;
     744             :     FeedbackSlot slot;
     745             :     FeedbackSlot literal_slot;
     746             :     FunctionLiteral* func;
     747             :   };
     748             :   ZoneVector<Declaration> declarations_;
     749             :   size_t constant_pool_entry_;
     750             :   bool has_constant_pool_entry_;
     751             : };
     752             : 
     753             : class BytecodeGenerator::CurrentScope final {
     754             :  public:
     755     5311257 :   CurrentScope(BytecodeGenerator* generator, Scope* scope)
     756             :       : generator_(generator), outer_scope_(generator->current_scope()) {
     757     5311257 :     if (scope != nullptr) {
     758             :       DCHECK_EQ(outer_scope_, scope->outer_scope());
     759             :       generator_->set_current_scope(scope);
     760             :     }
     761             :   }
     762             :   ~CurrentScope() {
     763     5311257 :     if (outer_scope_ != generator_->current_scope()) {
     764             :       generator_->set_current_scope(outer_scope_);
     765             :     }
     766             :   }
     767             : 
     768             :  private:
     769             :   BytecodeGenerator* generator_;
     770             :   Scope* outer_scope_;
     771             : };
     772             : 
     773             : class BytecodeGenerator::FeedbackSlotCache : public ZoneObject {
     774             :  public:
     775             :   typedef std::pair<TypeofMode, void*> Key;
     776             : 
     777             :   explicit FeedbackSlotCache(Zone* zone) : map_(zone) {}
     778             : 
     779             :   void Put(TypeofMode typeof_mode, Variable* variable, FeedbackSlot slot) {
     780             :     Key key = std::make_pair(typeof_mode, variable);
     781             :     auto entry = std::make_pair(key, slot);
     782             :     map_.insert(entry);
     783             :   }
     784             :   void Put(AstNode* node, FeedbackSlot slot) {
     785             :     Key key = std::make_pair(NOT_INSIDE_TYPEOF, node);
     786             :     auto entry = std::make_pair(key, slot);
     787             :     map_.insert(entry);
     788             :   }
     789             : 
     790     3897155 :   FeedbackSlot Get(TypeofMode typeof_mode, Variable* variable) const {
     791             :     Key key = std::make_pair(typeof_mode, variable);
     792             :     auto iter = map_.find(key);
     793     3897155 :     if (iter != map_.end()) {
     794     1480892 :       return iter->second;
     795             :     }
     796     2416263 :     return FeedbackSlot();
     797             :   }
     798     4157075 :   FeedbackSlot Get(AstNode* node) const {
     799             :     Key key = std::make_pair(NOT_INSIDE_TYPEOF, node);
     800             :     auto iter = map_.find(key);
     801     4157074 :     if (iter != map_.end()) {
     802           0 :       return iter->second;
     803             :     }
     804     4157074 :     return FeedbackSlot();
     805             :   }
     806             : 
     807             :  private:
     808             :   ZoneMap<Key, FeedbackSlot> map_;
     809             : };
     810             : 
     811    27708035 : BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
     812             :     : zone_(info->zone()),
     813             :       builder_(new (zone()) BytecodeArrayBuilder(
     814             :           info->isolate(), info->zone(), info->num_parameters_including_this(),
     815     2131327 :           info->scope()->num_stack_slots(), info->feedback_vector_spec(),
     816     2131325 :           info->SourcePositionRecordingMode())),
     817             :       info_(info),
     818     2131328 :       ast_string_constants_(info->isolate()->ast_string_constants()),
     819     2131328 :       closure_scope_(info->scope()),
     820     2131329 :       current_scope_(info->scope()),
     821             :       feedback_slot_cache_(new (zone()) FeedbackSlotCache(zone())),
     822     2131329 :       globals_builder_(new (zone()) GlobalDeclarationsBuilder(zone())),
     823             :       block_coverage_builder_(nullptr),
     824             :       global_declarations_(0, zone()),
     825             :       function_literals_(0, zone()),
     826             :       native_function_literals_(0, zone()),
     827             :       object_literals_(0, zone()),
     828             :       array_literals_(0, zone()),
     829             :       template_objects_(0, zone()),
     830             :       execution_control_(nullptr),
     831             :       execution_context_(nullptr),
     832             :       execution_result_(nullptr),
     833             :       incoming_new_target_or_generator_(),
     834             :       generator_jump_table_(nullptr),
     835             :       generator_state_(),
     836             :       loop_depth_(0),
     837    25575928 :       catch_prediction_(HandlerTable::UNCAUGHT) {
     838             :   DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
     839     2131326 :   if (info->has_source_range_map()) {
     840             :     block_coverage_builder_ = new (zone())
     841         781 :         BlockCoverageBuilder(zone(), builder(), info->source_range_map());
     842             :   }
     843     2131326 : }
     844             : 
     845     2131307 : Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
     846     4263395 :     Isolate* isolate, Handle<Script> script) {
     847             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
     848             : 
     849     2131307 :   AllocateDeferredConstants(isolate, script);
     850             : 
     851     2131307 :   if (block_coverage_builder_) {
     852             :     info()->set_coverage_info(
     853         781 :         isolate->factory()->NewCoverageInfo(block_coverage_builder_->slots()));
     854         781 :     if (FLAG_trace_block_coverage) {
     855           0 :       info()->coverage_info()->Print(info()->shared_info()->name());
     856             :     }
     857             :   }
     858             : 
     859     2131307 :   if (HasStackOverflow()) return Handle<BytecodeArray>();
     860     2131307 :   Handle<BytecodeArray> bytecode_array = builder()->ToBytecodeArray(isolate);
     861             : 
     862     2131308 :   if (incoming_new_target_or_generator_.is_valid()) {
     863             :     bytecode_array->set_incoming_new_target_or_generator_register(
     864             :         incoming_new_target_or_generator_);
     865             :   }
     866             : 
     867     2131308 :   return bytecode_array;
     868             : }
     869             : 
     870     2131307 : void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate,
     871     4517328 :                                                   Handle<Script> script) {
     872             :   // Build global declaration pair arrays.
     873     4440354 :   for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
     874             :     Handle<FixedArray> declarations =
     875       88870 :         globals_builder->AllocateDeclarations(info(), script);
     876       88870 :     if (declarations.is_null()) return SetStackOverflow();
     877             :     builder()->SetDeferredConstantPoolEntry(
     878       88870 :         globals_builder->constant_pool_entry(), declarations);
     879             :   }
     880             : 
     881             :   // Find or build shared function infos.
     882     8230928 :   for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
     883             :     FunctionLiteral* expr = literal.first;
     884             :     Handle<SharedFunctionInfo> shared_info =
     885     3968314 :         Compiler::GetSharedFunctionInfo(expr, script, isolate);
     886     3968314 :     if (shared_info.is_null()) return SetStackOverflow();
     887     3968314 :     builder()->SetDeferredConstantPoolEntry(literal.second, shared_info);
     888             :   }
     889             : 
     890             :   // Find or build shared function infos for the native function templates.
     891     4264292 :   for (std::pair<NativeFunctionLiteral*, size_t> literal :
     892        1678 :        native_function_literals_) {
     893        3356 :     NativeFunctionLiteral* expr = literal.first;
     894             :     Handle<SharedFunctionInfo> shared_info =
     895             :         Compiler::GetSharedFunctionInfoForNative(expr->extension(),
     896        1678 :                                                  expr->name());
     897        1678 :     if (shared_info.is_null()) return SetStackOverflow();
     898        1678 :     builder()->SetDeferredConstantPoolEntry(literal.second, shared_info);
     899             :   }
     900             : 
     901             :   // Build object literal constant properties
     902     4519312 :   for (std::pair<ObjectLiteral*, size_t> literal : object_literals_) {
     903      256698 :     ObjectLiteral* object_literal = literal.first;
     904      256698 :     if (object_literal->properties_count() > 0) {
     905             :       // If constant properties is an empty fixed array, we've already added it
     906             :       // to the constant pool when visiting the object literal.
     907             :       Handle<BoilerplateDescription> constant_properties =
     908             :           object_literal->GetOrBuildConstantProperties(isolate);
     909             : 
     910             :       builder()->SetDeferredConstantPoolEntry(literal.second,
     911      256698 :                                               constant_properties);
     912             :     }
     913             :   }
     914             : 
     915             :   // Build array literal constant elements
     916     4374073 :   for (std::pair<ArrayLiteral*, size_t> literal : array_literals_) {
     917             :     ArrayLiteral* array_literal = literal.first;
     918             :     Handle<ConstantElementsPair> constant_elements =
     919             :         array_literal->GetOrBuildConstantElements(isolate);
     920      111459 :     builder()->SetDeferredConstantPoolEntry(literal.second, constant_elements);
     921             :   }
     922             : 
     923             :   // Build template literals.
     924     4264053 :   for (std::pair<GetTemplateObject*, size_t> literal : template_objects_) {
     925             :     GetTemplateObject* get_template_object = literal.first;
     926             :     Handle<TemplateObjectDescription> description =
     927        1439 :         get_template_object->GetOrBuildDescription(isolate);
     928        1439 :     builder()->SetDeferredConstantPoolEntry(literal.second, description);
     929             :   }
     930             : }
     931             : 
     932     8701340 : void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
     933             :   DisallowHeapAllocation no_allocation;
     934             :   DisallowHandleAllocation no_handles;
     935             :   DisallowHandleDereference no_deref;
     936             : 
     937             :   InitializeAstVisitor(stack_limit);
     938             : 
     939             :   // Initialize the incoming context.
     940     2131320 :   ContextScope incoming_context(this, closure_scope());
     941             : 
     942             :   // Initialize control scope.
     943             :   ControlScopeForTopLevel control(this);
     944             : 
     945     2131326 :   RegisterAllocationScope register_scope(this);
     946             : 
     947     2131325 :   AllocateTopLevelRegisters();
     948             : 
     949     4262642 :   if (info()->literal()->CanSuspend()) {
     950        8286 :     BuildGeneratorPrologue();
     951             :   }
     952             : 
     953     2131323 :   if (closure_scope()->NeedsContext()) {
     954             :     // Push a new inner context scope for the function.
     955      176056 :     BuildNewLocalActivationContext();
     956      176056 :     ContextScope local_function_context(this, closure_scope());
     957      176056 :     BuildLocalActivationContextInitialization();
     958      176056 :     GenerateBytecodeBody();
     959             :   } else {
     960     1955267 :     GenerateBytecodeBody();
     961             :   }
     962             : 
     963             :   // Check that we are not falling off the end.
     964     2131325 :   DCHECK(!builder()->RequiresImplicitReturn());
     965     2131325 : }
     966             : 
     967    23445004 : void BytecodeGenerator::GenerateBytecodeBody() {
     968             :   // Build the arguments object if it is used.
     969     2131321 :   VisitArgumentsObject(closure_scope()->arguments());
     970             : 
     971             :   // Build rest arguments array if it is used.
     972             :   Variable* rest_parameter = closure_scope()->rest_parameter();
     973     2131323 :   VisitRestArgumentsArray(rest_parameter);
     974             : 
     975             :   // Build assignment to {.this_function} variable if it is used.
     976     2131323 :   VisitThisFunctionVariable(closure_scope()->this_function_var());
     977             : 
     978             :   // Build assignment to {new.target} variable if it is used.
     979     2131324 :   VisitNewTargetVariable(closure_scope()->new_target_var());
     980             : 
     981             :   // Create a generator object if necessary and initialize the
     982             :   // {.generator_object} variable.
     983     4262646 :   if (info()->literal()->CanSuspend()) {
     984        8286 :     BuildGeneratorObjectVariableInitialization();
     985             :   }
     986             : 
     987             :   // Emit tracing call if requested to do so.
     988     2131323 :   if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter);
     989             : 
     990             :   // Emit type profile call.
     991     2131323 :   if (info()->collect_type_profile()) {
     992          85 :     feedback_spec()->AddTypeProfileSlot();
     993             :     int num_parameters = closure_scope()->num_parameters();
     994         205 :     for (int i = 0; i < num_parameters; i++) {
     995         120 :       Register parameter(builder()->Parameter(i));
     996         120 :       builder()->LoadAccumulatorWithRegister(parameter).CollectTypeProfile(
     997         240 :           closure_scope()->parameter(i)->initializer_position());
     998             :     }
     999             :   }
    1000             : 
    1001             :   // Visit declarations within the function scope.
    1002     2131323 :   VisitDeclarations(closure_scope()->declarations());
    1003             : 
    1004             :   // Emit initializing assignments for module namespace imports (if any).
    1005     2131325 :   VisitModuleNamespaceImports();
    1006             : 
    1007             :   // Perform a stack-check before the body.
    1008     4262648 :   builder()->StackCheck(info()->literal()->start_position());
    1009             : 
    1010             :   // Visit statements in the function body.
    1011     2131325 :   VisitStatements(info()->literal()->body());
    1012             : 
    1013             :   // Emit an implicit return instruction in case control flow can fall off the
    1014             :   // end of the function without an explicit return being present on all paths.
    1015     2131326 :   if (builder()->RequiresImplicitReturn()) {
    1016      409670 :     builder()->LoadUndefined();
    1017      409670 :     BuildReturn();
    1018             :   }
    1019     2131326 : }
    1020             : 
    1021     4262640 : void BytecodeGenerator::AllocateTopLevelRegisters() {
    1022     4262640 :   if (info()->literal()->CanSuspend()) {
    1023             :     // Allocate a register for generator_state_.
    1024        8286 :     generator_state_ = register_allocator()->NewRegister();
    1025             :     // Either directly use generator_object_var or allocate a new register for
    1026             :     // the incoming generator object.
    1027        8286 :     Variable* generator_object_var = closure_scope()->generator_object_var();
    1028        8286 :     if (generator_object_var->location() == VariableLocation::LOCAL) {
    1029             :       incoming_new_target_or_generator_ =
    1030        7219 :           GetRegisterForLocalVariable(generator_object_var);
    1031             :     } else {
    1032        1067 :       incoming_new_target_or_generator_ = register_allocator()->NewRegister();
    1033             :     }
    1034     2123034 :   } else if (closure_scope()->new_target_var()) {
    1035             :     // Either directly use new_target_var or allocate a new register for
    1036             :     // the incoming new target object.
    1037      102885 :     Variable* new_target_var = closure_scope()->new_target_var();
    1038      102885 :     if (new_target_var->location() == VariableLocation::LOCAL) {
    1039             :       incoming_new_target_or_generator_ =
    1040       14261 :           GetRegisterForLocalVariable(new_target_var);
    1041             :     } else {
    1042       88624 :       incoming_new_target_or_generator_ = register_allocator()->NewRegister();
    1043             :     }
    1044             :   }
    1045     2131320 : }
    1046             : 
    1047      222629 : void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
    1048             :                                              LoopBuilder* loop_builder) {
    1049             :   VisitIterationHeader(stmt->first_suspend_id(), stmt->suspend_count(),
    1050      222629 :                        loop_builder);
    1051           0 : }
    1052             : 
    1053      222872 : void BytecodeGenerator::VisitIterationHeader(int first_suspend_id,
    1054             :                                              int suspend_count,
    1055        4344 :                                              LoopBuilder* loop_builder) {
    1056             :   // Recall that suspend_count is always zero inside ordinary (i.e.
    1057             :   // non-generator) functions.
    1058      222872 :   if (suspend_count == 0) {
    1059      221786 :     loop_builder->LoopHeader();
    1060             :   } else {
    1061             :     loop_builder->LoopHeaderInGenerator(&generator_jump_table_,
    1062        1086 :                                         first_suspend_id, suspend_count);
    1063             : 
    1064             :     // Perform state dispatch on the generator state, assuming this is a resume.
    1065             :     builder()
    1066        1086 :         ->LoadAccumulatorWithRegister(generator_state_)
    1067        2172 :         .SwitchOnSmiNoFeedback(generator_jump_table_);
    1068             : 
    1069             :     // We fall through when the generator state is not in the jump table. If we
    1070             :     // are not resuming, we want to fall through to the loop body.
    1071             :     // TODO(leszeks): Only generate this test for debug builds, we can skip it
    1072             :     // entirely in release assuming that the generator states is always valid.
    1073             :     BytecodeLabel not_resuming;
    1074             :     builder()
    1075        1086 :         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    1076        1086 :         .CompareOperation(Token::Value::EQ_STRICT, generator_state_)
    1077        1086 :         .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &not_resuming);
    1078             : 
    1079             :     // Otherwise this is an error.
    1080        1086 :     builder()->Abort(BailoutReason::kInvalidJumpTableIndex);
    1081             : 
    1082        1086 :     builder()->Bind(&not_resuming);
    1083             :   }
    1084      222872 : }
    1085             : 
    1086       49716 : void BytecodeGenerator::BuildGeneratorPrologue() {
    1087             :   DCHECK_GT(info()->literal()->suspend_count(), 0);
    1088             :   DCHECK(generator_state_.is_valid());
    1089             :   DCHECK(generator_object().is_valid());
    1090             :   generator_jump_table_ =
    1091       16572 :       builder()->AllocateJumpTable(info()->literal()->suspend_count(), 0);
    1092             : 
    1093             :   BytecodeLabel regular_call;
    1094             :   builder()
    1095        8286 :       ->LoadAccumulatorWithRegister(generator_object())
    1096        8286 :       .JumpIfUndefined(&regular_call);
    1097             : 
    1098             :   // This is a resume call. Restore the current context and the registers,
    1099             :   // then perform state dispatch.
    1100             :   {
    1101             :     RegisterAllocationScope register_scope(this);
    1102        8286 :     Register generator_context = register_allocator()->NewRegister();
    1103             :     builder()
    1104        8286 :         ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object())
    1105        8286 :         .PushContext(generator_context)
    1106        8286 :         .RestoreGeneratorState(generator_object())
    1107        8286 :         .StoreAccumulatorInRegister(generator_state_)
    1108       16572 :         .SwitchOnSmiNoFeedback(generator_jump_table_);
    1109             :   }
    1110             :   // We fall through when the generator state is not in the jump table.
    1111             :   // TODO(leszeks): Only generate this for debug builds.
    1112        8286 :   builder()->Abort(BailoutReason::kInvalidJumpTableIndex);
    1113             : 
    1114             :   // This is a regular call.
    1115             :   builder()
    1116        8286 :       ->Bind(&regular_call)
    1117        8286 :       .LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    1118        8286 :       .StoreAccumulatorInRegister(generator_state_);
    1119             :   // Now fall through to the ordinary function prologue, after which we will run
    1120             :   // into the generator object creation and other extra code inserted by the
    1121             :   // parser.
    1122        8286 : }
    1123             : 
    1124    10314960 : void BytecodeGenerator::VisitBlock(Block* stmt) {
    1125             :   // Visit declarations and statements.
    1126             :   CurrentScope current_scope(this, stmt->scope());
    1127     5297794 :   if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
    1128       21426 :     BuildNewLocalBlockContext(stmt->scope());
    1129       21426 :     ContextScope scope(this, stmt->scope());
    1130       21426 :     VisitBlockDeclarationsAndStatements(stmt);
    1131             :   } else {
    1132     5125341 :     VisitBlockDeclarationsAndStatements(stmt);
    1133             :   }
    1134     5146767 : }
    1135             : 
    1136    15440301 : void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
    1137     5146767 :   BlockBuilder block_builder(builder(), block_coverage_builder_, stmt);
    1138             :   ControlScopeForBreakable execution_control(this, stmt, &block_builder);
    1139     5146767 :   if (stmt->scope() != nullptr) {
    1140      151027 :     VisitDeclarations(stmt->scope()->declarations());
    1141             :   }
    1142     5146767 :   VisitStatements(stmt->statements());
    1143     5146766 : }
    1144             : 
    1145     5605855 : void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
    1146     5585697 :   Variable* variable = decl->proxy()->var();
    1147     3996868 :   switch (variable->location()) {
    1148             :     case VariableLocation::UNALLOCATED: {
    1149             :       DCHECK(!variable->binding_needs_init());
    1150             :       FeedbackSlot slot =
    1151      911195 :           GetCachedLoadGlobalICSlot(NOT_INSIDE_TYPEOF, variable);
    1152             :       globals_builder()->AddUndefinedDeclaration(variable->raw_name(), slot);
    1153             :       break;
    1154             :     }
    1155             :     case VariableLocation::LOCAL:
    1156     1463470 :       if (variable->binding_needs_init()) {
    1157        3153 :         Register destination(builder()->Local(variable->index()));
    1158        3153 :         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    1159             :       }
    1160             :       break;
    1161             :     case VariableLocation::PARAMETER:
    1162         690 :       if (variable->binding_needs_init()) {
    1163           0 :         Register destination(builder()->Parameter(variable->index()));
    1164           0 :         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    1165             :       }
    1166             :       break;
    1167             :     case VariableLocation::CONTEXT:
    1168     1320958 :       if (variable->binding_needs_init()) {
    1169             :         DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
    1170      391513 :         builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
    1171      391513 :                                                   variable->index(), 0);
    1172             :       }
    1173             :       break;
    1174             :     case VariableLocation::LOOKUP: {
    1175             :       DCHECK_EQ(VAR, variable->mode());
    1176             :       DCHECK(!variable->binding_needs_init());
    1177             : 
    1178      282968 :       Register name = register_allocator()->NewRegister();
    1179             : 
    1180             :       builder()
    1181      282968 :           ->LoadLiteral(variable->raw_name())
    1182      282968 :           .StoreAccumulatorInRegister(name)
    1183      282968 :           .CallRuntime(Runtime::kDeclareEvalVar, name);
    1184             :       break;
    1185             :     }
    1186             :     case VariableLocation::MODULE:
    1187       17587 :       if (variable->IsExport() && variable->binding_needs_init()) {
    1188       17005 :         builder()->LoadTheHole();
    1189       17005 :         BuildVariableAssignment(variable, Token::INIT, HoleCheckMode::kElided);
    1190             :       }
    1191             :       // Nothing to do for imports.
    1192             :       break;
    1193             :   }
    1194     3996868 : }
    1195             : 
    1196     2490676 : void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
    1197     1504229 :   Variable* variable = decl->proxy()->var();
    1198             :   DCHECK(variable->mode() == LET || variable->mode() == VAR);
    1199      789870 :   switch (variable->location()) {
    1200             :     case VariableLocation::UNALLOCATED: {
    1201             :       FeedbackSlot slot =
    1202      188756 :           GetCachedLoadGlobalICSlot(NOT_INSIDE_TYPEOF, variable);
    1203      188756 :       FeedbackSlot literal_slot = GetCachedCreateClosureSlot(decl->fun());
    1204             :       globals_builder()->AddFunctionDeclaration(variable->raw_name(), slot,
    1205             :                                                 literal_slot, decl->fun());
    1206             :       break;
    1207             :     }
    1208             :     case VariableLocation::PARAMETER:
    1209             :     case VariableLocation::LOCAL: {
    1210       75175 :       VisitForAccumulatorValue(decl->fun());
    1211       75175 :       BuildVariableAssignment(variable, Token::INIT, HoleCheckMode::kElided);
    1212       75175 :       break;
    1213             :     }
    1214             :     case VariableLocation::CONTEXT: {
    1215             :       DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
    1216      517782 :       VisitForAccumulatorValue(decl->fun());
    1217             :       builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
    1218      517782 :                                   0);
    1219      517782 :       break;
    1220             :     }
    1221             :     case VariableLocation::LOOKUP: {
    1222        7821 :       RegisterList args = register_allocator()->NewRegisterList(2);
    1223             :       builder()
    1224        7821 :           ->LoadLiteral(variable->raw_name())
    1225        7821 :           .StoreAccumulatorInRegister(args[0]);
    1226        7821 :       VisitForAccumulatorValue(decl->fun());
    1227        7821 :       builder()->StoreAccumulatorInRegister(args[1]).CallRuntime(
    1228        7821 :           Runtime::kDeclareEvalFunction, args);
    1229             :       break;
    1230             :     }
    1231             :     case VariableLocation::MODULE:
    1232             :       DCHECK_EQ(variable->mode(), LET);
    1233             :       DCHECK(variable->IsExport());
    1234         336 :       VisitForAccumulatorValue(decl->fun());
    1235         336 :       BuildVariableAssignment(variable, Token::INIT, HoleCheckMode::kElided);
    1236         336 :       break;
    1237             :   }
    1238      789870 : }
    1239             : 
    1240     2132571 : void BytecodeGenerator::VisitModuleNamespaceImports() {
    1241     4261581 :   if (!closure_scope()->is_module_scope()) return;
    1242             : 
    1243             :   RegisterAllocationScope register_scope(this);
    1244        1067 :   Register module_request = register_allocator()->NewRegister();
    1245             : 
    1246        1067 :   ModuleDescriptor* descriptor = closure_scope()->AsModuleScope()->module();
    1247        2224 :   for (auto entry : descriptor->namespace_imports()) {
    1248             :     builder()
    1249         180 :         ->LoadLiteral(Smi::FromInt(entry->module_request))
    1250          90 :         .StoreAccumulatorInRegister(module_request)
    1251          90 :         .CallRuntime(Runtime::kGetModuleNamespace, module_request);
    1252         180 :     Variable* var = closure_scope()->LookupLocal(entry->local_name);
    1253             :     DCHECK_NOT_NULL(var);
    1254          90 :     BuildVariableAssignment(var, Token::INIT, HoleCheckMode::kElided);
    1255        1067 :   }
    1256             : }
    1257             : 
    1258     5305479 : void BytecodeGenerator::VisitDeclarations(Declaration::List* declarations) {
    1259             :   RegisterAllocationScope register_scope(this);
    1260             :   DCHECK(globals_builder()->empty());
    1261     9470126 :   for (Declaration* decl : *declarations) {
    1262             :     RegisterAllocationScope register_scope(this);
    1263     4786737 :     Visit(decl);
    1264     4786738 :   }
    1265     4594520 :   if (globals_builder()->empty()) return;
    1266             : 
    1267             :   globals_builder()->set_constant_pool_entry(
    1268       88870 :       builder()->AllocateDeferredConstantPoolEntry());
    1269       88870 :   int encoded_flags = info()->GetDeclareGlobalsFlags();
    1270             : 
    1271             :   // Emit code to declare globals.
    1272       88870 :   RegisterList args = register_allocator()->NewRegisterList(3);
    1273             :   builder()
    1274      177740 :       ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
    1275       88870 :       .StoreAccumulatorInRegister(args[0])
    1276       88870 :       .LoadLiteral(Smi::FromInt(encoded_flags))
    1277       88870 :       .StoreAccumulatorInRegister(args[1])
    1278      177740 :       .MoveRegister(Register::function_closure(), args[2])
    1279       88870 :       .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, args);
    1280             : 
    1281             :   // Push and reset globals builder.
    1282      177740 :   global_declarations_.push_back(globals_builder());
    1283       88870 :   globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
    1284             : }
    1285             : 
    1286    28984316 : void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
    1287    43211236 :   for (int i = 0; i < statements->length(); i++) {
    1288             :     // Allocate an outer register allocations scope for the statement.
    1289             :     RegisterAllocationScope allocation_scope(this);
    1290    16256450 :     Statement* stmt = statements->at(i);
    1291    16256450 :     Visit(stmt);
    1292    16256456 :     if (stmt->IsJump()) break;
    1293    14226921 :   }
    1294     7378704 : }
    1295             : 
    1296    18694546 : void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
    1297             :   builder()->SetStatementPosition(stmt);
    1298     9347273 :   VisitForEffect(stmt->expression());
    1299     9347276 : }
    1300             : 
    1301           0 : void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
    1302           0 : }
    1303             : 
    1304     7004593 : void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
    1305             :   ConditionalControlFlowBuilder conditional_builder(
    1306     1935326 :       builder(), block_coverage_builder_, stmt);
    1307             :   builder()->SetStatementPosition(stmt);
    1308             : 
    1309      967663 :   if (stmt->condition()->ToBooleanIsTrue()) {
    1310             :     // Generate then block unconditionally as always true.
    1311         332 :     conditional_builder.Then();
    1312         332 :     Visit(stmt->then_statement());
    1313      967331 :   } else if (stmt->condition()->ToBooleanIsFalse()) {
    1314             :     // Generate else block unconditionally if it exists.
    1315        8355 :     if (stmt->HasElseStatement()) {
    1316        7058 :       conditional_builder.Else();
    1317        7058 :       Visit(stmt->else_statement());
    1318             :     }
    1319             :   } else {
    1320             :     // TODO(oth): If then statement is BreakStatement or
    1321             :     // ContinueStatement we can reduce number of generated
    1322             :     // jump/jump_ifs here. See BasicLoops test.
    1323             :     VisitForTest(stmt->condition(), conditional_builder.then_labels(),
    1324      958976 :                  conditional_builder.else_labels(), TestFallthrough::kThen);
    1325             : 
    1326      958975 :     conditional_builder.Then();
    1327      958975 :     Visit(stmt->then_statement());
    1328             : 
    1329      958975 :     if (stmt->HasElseStatement()) {
    1330      241269 :       conditional_builder.JumpToEnd();
    1331      241269 :       conditional_builder.Else();
    1332      241269 :       Visit(stmt->else_statement());
    1333             :     }
    1334      967662 :   }
    1335      967663 : }
    1336             : 
    1337        3409 : void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
    1338        3409 :     SloppyBlockFunctionStatement* stmt) {
    1339        3409 :   Visit(stmt->statement());
    1340        3409 : }
    1341             : 
    1342       26178 : void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
    1343             :   AllocateBlockCoverageSlotIfEnabled(stmt, SourceRangeKind::kContinuation);
    1344             :   builder()->SetStatementPosition(stmt);
    1345             :   execution_control()->Continue(stmt->target());
    1346        8726 : }
    1347             : 
    1348      203973 : void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
    1349             :   AllocateBlockCoverageSlotIfEnabled(stmt, SourceRangeKind::kContinuation);
    1350             :   builder()->SetStatementPosition(stmt);
    1351             :   execution_control()->Break(stmt->target());
    1352       67991 : }
    1353             : 
    1354     8689275 : void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    1355             :   AllocateBlockCoverageSlotIfEnabled(stmt, SourceRangeKind::kContinuation);
    1356             :   builder()->SetStatementPosition(stmt);
    1357     2172318 :   VisitForAccumulatorValue(stmt->expression());
    1358     2172321 :   if (stmt->is_async_return()) {
    1359             :     execution_control()->AsyncReturnAccumulator(stmt->end_position());
    1360             :   } else {
    1361             :     execution_control()->ReturnAccumulator(stmt->end_position());
    1362             :   }
    1363     2172321 : }
    1364             : 
    1365       12096 : void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
    1366             :   builder()->SetStatementPosition(stmt);
    1367        3024 :   VisitForAccumulatorValue(stmt->expression());
    1368        3024 :   BuildNewLocalWithContext(stmt->scope());
    1369        3024 :   VisitInScope(stmt->statement(), stmt->scope());
    1370        3024 : }
    1371             : 
    1372      159953 : void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
    1373             :   // We need this scope because we visit for register values. We have to
    1374             :   // maintain a execution result scope where registers can be allocated.
    1375      251229 :   ZoneList<CaseClause*>* clauses = stmt->cases();
    1376             :   SwitchBuilder switch_builder(builder(), block_coverage_builder_, stmt,
    1377       33342 :                                clauses->length());
    1378             :   ControlScopeForBreakable scope(this, stmt, &switch_builder);
    1379             :   int default_index = -1;
    1380             : 
    1381             :   builder()->SetStatementPosition(stmt);
    1382             : 
    1383             :   // Keep the switch value in a register until a case matches.
    1384       16671 :   Register tag = VisitForRegisterValue(stmt->tag());
    1385             : 
    1386             :   // Iterate over all cases and create nodes for label comparison.
    1387      234558 :   for (int i = 0; i < clauses->length(); i++) {
    1388      100608 :     CaseClause* clause = clauses->at(i);
    1389             : 
    1390             :     // The default is not a test, remember index.
    1391      100608 :     if (clause->is_default()) {
    1392             :       default_index = i;
    1393             :       continue;
    1394             :     }
    1395             : 
    1396             :     // Perform label comparison as if via '===' with tag.
    1397       93269 :     VisitForAccumulatorValue(clause->label());
    1398             :     builder()->CompareOperation(
    1399             :         Token::Value::EQ_STRICT, tag,
    1400      186538 :         feedback_index(feedback_spec()->AddCompareICSlot()));
    1401       93269 :     switch_builder.Case(ToBooleanMode::kAlreadyBoolean, i);
    1402             :   }
    1403             : 
    1404       16671 :   if (default_index >= 0) {
    1405             :     // Emit default jump if there is a default case.
    1406        7339 :     switch_builder.DefaultAt(default_index);
    1407             :   } else {
    1408             :     // Otherwise if we have reached here none of the cases matched, so jump to
    1409             :     // the end.
    1410             :     switch_builder.Break();
    1411             :   }
    1412             : 
    1413             :   // Iterate over all cases and create the case bodies.
    1414      217887 :   for (int i = 0; i < clauses->length(); i++) {
    1415      201216 :     CaseClause* clause = clauses->at(i);
    1416      100608 :     switch_builder.SetCaseTarget(i, clause);
    1417      100608 :     VisitStatements(clause->statements());
    1418       16671 :   }
    1419       16671 : }
    1420             : 
    1421      445998 : void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
    1422      222999 :                                            LoopBuilder* loop_builder) {
    1423      222999 :   loop_builder->LoopBody();
    1424             :   ControlScopeForIteration execution_control(this, stmt, loop_builder);
    1425      445998 :   builder()->StackCheck(stmt->position());
    1426      222999 :   Visit(stmt->body());
    1427      222999 :   loop_builder->BindContinueTarget();
    1428      222999 : }
    1429             : 
    1430       19186 : void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
    1431        5896 :   LoopBuilder loop_builder(builder(), block_coverage_builder_, stmt);
    1432        2948 :   if (stmt->cond()->ToBooleanIsFalse()) {
    1433         370 :     VisitIterationBody(stmt, &loop_builder);
    1434        2578 :   } else if (stmt->cond()->ToBooleanIsTrue()) {
    1435             :     VisitIterationHeader(stmt, &loop_builder);
    1436         637 :     VisitIterationBody(stmt, &loop_builder);
    1437         637 :     loop_builder.JumpToHeader(loop_depth_);
    1438             :   } else {
    1439             :     VisitIterationHeader(stmt, &loop_builder);
    1440        1941 :     VisitIterationBody(stmt, &loop_builder);
    1441             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1442             :     BytecodeLabels loop_backbranch(zone());
    1443             :     VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
    1444        1941 :                  TestFallthrough::kThen);
    1445        1941 :     loop_backbranch.Bind(builder());
    1446        1941 :     loop_builder.JumpToHeader(loop_depth_);
    1447        2948 :   }
    1448        2948 : }
    1449             : 
    1450      126069 : void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
    1451       34794 :   LoopBuilder loop_builder(builder(), block_coverage_builder_, stmt);
    1452             : 
    1453       17397 :   if (stmt->cond()->ToBooleanIsFalse()) {
    1454             :     // If the condition is false there is no need to generate the loop.
    1455         103 :     return;
    1456             :   }
    1457             : 
    1458             :   VisitIterationHeader(stmt, &loop_builder);
    1459       17294 :   if (!stmt->cond()->ToBooleanIsTrue()) {
    1460             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1461             :     BytecodeLabels loop_body(zone());
    1462             :     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
    1463       14146 :                  TestFallthrough::kThen);
    1464       14146 :     loop_body.Bind(builder());
    1465             :   }
    1466       17294 :   VisitIterationBody(stmt, &loop_builder);
    1467       17294 :   loop_builder.JumpToHeader(loop_depth_);
    1468             : }
    1469             : 
    1470     2011976 : void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
    1471      375458 :   LoopBuilder loop_builder(builder(), block_coverage_builder_, stmt);
    1472             : 
    1473      187729 :   if (stmt->init() != nullptr) {
    1474      133175 :     Visit(stmt->init());
    1475             :   }
    1476      187729 :   if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
    1477             :     // If the condition is known to be false there is no need to generate
    1478             :     // body, next or condition blocks. Init block should be generated.
    1479       15464 :     return;
    1480             :   }
    1481             : 
    1482             :   VisitIterationHeader(stmt, &loop_builder);
    1483      172265 :   if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
    1484             :     builder()->SetExpressionAsStatementPosition(stmt->cond());
    1485             :     BytecodeLabels loop_body(zone());
    1486             :     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
    1487      155482 :                  TestFallthrough::kThen);
    1488      155482 :     loop_body.Bind(builder());
    1489             :   }
    1490      172265 :   VisitIterationBody(stmt, &loop_builder);
    1491      172265 :   if (stmt->next() != nullptr) {
    1492             :     builder()->SetStatementPosition(stmt->next());
    1493      147301 :     Visit(stmt->next());
    1494             :   }
    1495      172265 :   loop_builder.JumpToHeader(loop_depth_);
    1496             : }
    1497             : 
    1498        6501 : void BytecodeGenerator::VisitForInAssignment(Expression* expr) {
    1499             :   DCHECK(expr->IsValidReferenceExpression());
    1500             : 
    1501             :   // Evaluate assignment starting with the value to be stored in the
    1502             :   // accumulator.
    1503        6368 :   Property* property = expr->AsProperty();
    1504        6072 :   LhsKind assign_type = Property::GetAssignType(property);
    1505        6072 :   switch (assign_type) {
    1506             :     case VARIABLE: {
    1507       11848 :       VariableProxy* proxy = expr->AsVariableProxy();
    1508             :       BuildVariableAssignment(proxy->var(), Token::ASSIGN,
    1509        5924 :                               proxy->hole_check_mode());
    1510        5924 :       break;
    1511             :     }
    1512             :     case NAMED_PROPERTY: {
    1513             :       RegisterAllocationScope register_scope(this);
    1514          23 :       Register value = register_allocator()->NewRegister();
    1515          23 :       builder()->StoreAccumulatorInRegister(value);
    1516          23 :       Register object = VisitForRegisterValue(property->obj());
    1517             :       const AstRawString* name =
    1518          46 :           property->key()->AsLiteral()->AsRawPropertyName();
    1519          23 :       builder()->LoadAccumulatorWithRegister(value);
    1520          23 :       FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
    1521             :       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    1522          23 :                                     language_mode());
    1523          23 :       break;
    1524             :     }
    1525             :     case KEYED_PROPERTY: {
    1526             :       RegisterAllocationScope register_scope(this);
    1527         110 :       Register value = register_allocator()->NewRegister();
    1528         110 :       builder()->StoreAccumulatorInRegister(value);
    1529         110 :       Register object = VisitForRegisterValue(property->obj());
    1530         110 :       Register key = VisitForRegisterValue(property->key());
    1531         110 :       builder()->LoadAccumulatorWithRegister(value);
    1532         110 :       FeedbackSlot slot = feedback_spec()->AddKeyedStoreICSlot(language_mode());
    1533             :       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    1534         110 :                                     language_mode());
    1535         110 :       break;
    1536             :     }
    1537             :     case NAMED_SUPER_PROPERTY: {
    1538             :       RegisterAllocationScope register_scope(this);
    1539           5 :       RegisterList args = register_allocator()->NewRegisterList(4);
    1540           5 :       builder()->StoreAccumulatorInRegister(args[3]);
    1541          10 :       SuperPropertyReference* super_property =
    1542           5 :           property->obj()->AsSuperPropertyReference();
    1543             :       VisitForRegisterValue(super_property->this_var(), args[0]);
    1544             :       VisitForRegisterValue(super_property->home_object(), args[1]);
    1545             :       builder()
    1546          15 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    1547           5 :           .StoreAccumulatorInRegister(args[2])
    1548           5 :           .CallRuntime(StoreToSuperRuntimeId(), args);
    1549           5 :       break;
    1550             :     }
    1551             :     case KEYED_SUPER_PROPERTY: {
    1552             :       RegisterAllocationScope register_scope(this);
    1553          10 :       RegisterList args = register_allocator()->NewRegisterList(4);
    1554          10 :       builder()->StoreAccumulatorInRegister(args[3]);
    1555          20 :       SuperPropertyReference* super_property =
    1556          10 :           property->obj()->AsSuperPropertyReference();
    1557             :       VisitForRegisterValue(super_property->this_var(), args[0]);
    1558             :       VisitForRegisterValue(super_property->home_object(), args[1]);
    1559             :       VisitForRegisterValue(property->key(), args[2]);
    1560          10 :       builder()->CallRuntime(StoreKeyedToSuperRuntimeId(), args);
    1561          10 :       break;
    1562             :     }
    1563             :   }
    1564        6072 : }
    1565             : 
    1566      121530 : void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
    1567       12234 :   if (stmt->subject()->IsNullLiteral() ||
    1568        6100 :       stmt->subject()->IsUndefinedLiteral()) {
    1569             :     // ForIn generates lots of code, skip if it wouldn't produce any effects.
    1570          62 :     return;
    1571             :   }
    1572             : 
    1573             :   BytecodeLabel subject_null_label, subject_undefined_label;
    1574        6072 :   FeedbackSlot slot = feedback_spec()->AddForInSlot();
    1575             : 
    1576             :   // Prepare the state for executing ForIn.
    1577             :   builder()->SetExpressionAsStatementPosition(stmt->subject());
    1578        6072 :   VisitForAccumulatorValue(stmt->subject());
    1579        6072 :   builder()->JumpIfUndefined(&subject_undefined_label);
    1580        6072 :   builder()->JumpIfNull(&subject_null_label);
    1581        6072 :   Register receiver = register_allocator()->NewRegister();
    1582        6072 :   builder()->ToObject(receiver);
    1583             : 
    1584             :   // Used as kRegTriple and kRegPair in ForInPrepare and ForInNext.
    1585        6072 :   RegisterList triple = register_allocator()->NewRegisterList(3);
    1586        6072 :   Register cache_length = triple[2];
    1587        6072 :   builder()->ForInEnumerate(receiver);
    1588        6072 :   builder()->ForInPrepare(triple, feedback_index(slot));
    1589             : 
    1590             :   // Set up loop counter
    1591        6072 :   Register index = register_allocator()->NewRegister();
    1592        6072 :   builder()->LoadLiteral(Smi::kZero);
    1593        6072 :   builder()->StoreAccumulatorInRegister(index);
    1594             : 
    1595             :   // The loop
    1596             :   {
    1597       12144 :     LoopBuilder loop_builder(builder(), block_coverage_builder_, stmt);
    1598             :     VisitIterationHeader(stmt, &loop_builder);
    1599             :     builder()->SetExpressionAsStatementPosition(stmt->each());
    1600        6072 :     builder()->ForInContinue(index, cache_length);
    1601             :     loop_builder.BreakIfFalse(ToBooleanMode::kAlreadyBoolean);
    1602             :     builder()->ForInNext(receiver, index, triple.Truncate(2),
    1603        6072 :                          feedback_index(slot));
    1604             :     loop_builder.ContinueIfUndefined();
    1605        6072 :     VisitForInAssignment(stmt->each());
    1606        6072 :     VisitIterationBody(stmt, &loop_builder);
    1607        6072 :     builder()->ForInStep(index);
    1608        6072 :     builder()->StoreAccumulatorInRegister(index);
    1609        6072 :     loop_builder.JumpToHeader(loop_depth_);
    1610             :   }
    1611        6072 :   builder()->Bind(&subject_null_label);
    1612        6072 :   builder()->Bind(&subject_undefined_label);
    1613             : }
    1614             : 
    1615      195360 : void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
    1616       48840 :   LoopBuilder loop_builder(builder(), block_coverage_builder_, stmt);
    1617             : 
    1618             :   builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
    1619       24420 :   VisitForEffect(stmt->assign_iterator());
    1620             : 
    1621             :   VisitIterationHeader(stmt, &loop_builder);
    1622             :   builder()->SetExpressionAsStatementPosition(stmt->next_result());
    1623       24420 :   VisitForEffect(stmt->next_result());
    1624       24420 :   TypeHint type_hint = VisitForAccumulatorValue(stmt->result_done());
    1625             :   loop_builder.BreakIfTrue(ToBooleanModeFromTypeHint(type_hint));
    1626             : 
    1627       24420 :   VisitForEffect(stmt->assign_each());
    1628       24420 :   VisitIterationBody(stmt, &loop_builder);
    1629       24420 :   loop_builder.JumpToHeader(loop_depth_);
    1630       24420 : }
    1631             : 
    1632      894701 : void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
    1633             :   // Update catch prediction tracking. The updated catch_prediction value lasts
    1634             :   // until the end of the try_block in the AST node, and does not apply to the
    1635             :   // catch_block.
    1636             :   HandlerTable::CatchPrediction outer_catch_prediction = catch_prediction();
    1637             :   set_catch_prediction(stmt->GetCatchPrediction(outer_catch_prediction));
    1638             : 
    1639             :   TryCatchBuilder try_control_builder(builder(), catch_prediction());
    1640             : 
    1641             :   // Preserve the context in a dedicated register, so that it can be restored
    1642             :   // when the handler is entered by the stack-unwinding machinery.
    1643             :   // TODO(mstarzinger): Be smarter about register allocation.
    1644      102122 :   Register context = register_allocator()->NewRegister();
    1645      204244 :   builder()->MoveRegister(Register::current_context(), context);
    1646             : 
    1647             :   // Evaluate the try-block inside a control scope. This simulates a handler
    1648             :   // that is intercepting 'throw' control commands.
    1649      102122 :   try_control_builder.BeginTry(context);
    1650             :   {
    1651             :     ControlScopeForTryCatch scope(this, &try_control_builder);
    1652      102122 :     Visit(stmt->try_block());
    1653             :     set_catch_prediction(outer_catch_prediction);
    1654             :   }
    1655      102122 :   try_control_builder.EndTry();
    1656             : 
    1657             :   // Create a catch scope that binds the exception.
    1658      102122 :   BuildNewLocalCatchContext(stmt->scope());
    1659      102122 :   builder()->StoreAccumulatorInRegister(context);
    1660             : 
    1661             :   // If requested, clear message object as we enter the catch block.
    1662      102122 :   if (stmt->ShouldClearPendingException(outer_catch_prediction)) {
    1663       77725 :     builder()->LoadTheHole().SetPendingMessage();
    1664             :   }
    1665             : 
    1666             :   // Load the catch context into the accumulator.
    1667      102122 :   builder()->LoadAccumulatorWithRegister(context);
    1668             : 
    1669             :   // Evaluate the catch-block.
    1670             :   BuildIncrementBlockCoverageCounterIfEnabled(stmt, SourceRangeKind::kCatch);
    1671      102122 :   VisitInScope(stmt->catch_block(), stmt->scope());
    1672      102122 :   try_control_builder.EndCatch();
    1673             :   BuildIncrementBlockCoverageCounterIfEnabled(stmt,
    1674             :                                               SourceRangeKind::kContinuation);
    1675      102122 : }
    1676             : 
    1677      181560 : void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
    1678             :   // We can't know whether the finally block will override ("catch") an
    1679             :   // exception thrown in the try block, so we just adopt the outer prediction.
    1680       36312 :   TryFinallyBuilder try_control_builder(builder(), catch_prediction());
    1681             : 
    1682             :   // We keep a record of all paths that enter the finally-block to be able to
    1683             :   // dispatch to the correct continuation point after the statements in the
    1684             :   // finally-block have been evaluated.
    1685             :   //
    1686             :   // The try-finally construct can enter the finally-block in three ways:
    1687             :   // 1. By exiting the try-block normally, falling through at the end.
    1688             :   // 2. By exiting the try-block with a function-local control flow transfer
    1689             :   //    (i.e. through break/continue/return statements).
    1690             :   // 3. By exiting the try-block with a thrown exception.
    1691             :   //
    1692             :   // The result register semantics depend on how the block was entered:
    1693             :   //  - ReturnStatement: It represents the return value being returned.
    1694             :   //  - ThrowStatement: It represents the exception being thrown.
    1695             :   //  - BreakStatement/ContinueStatement: Undefined and not used.
    1696             :   //  - Falling through into finally-block: Undefined and not used.
    1697       36312 :   Register token = register_allocator()->NewRegister();
    1698       36312 :   Register result = register_allocator()->NewRegister();
    1699             :   ControlScope::DeferredCommands commands(this, token, result);
    1700             : 
    1701             :   // Preserve the context in a dedicated register, so that it can be restored
    1702             :   // when the handler is entered by the stack-unwinding machinery.
    1703             :   // TODO(mstarzinger): Be smarter about register allocation.
    1704       36312 :   Register context = register_allocator()->NewRegister();
    1705       72624 :   builder()->MoveRegister(Register::current_context(), context);
    1706             : 
    1707             :   // Evaluate the try-block inside a control scope. This simulates a handler
    1708             :   // that is intercepting all control commands.
    1709       36312 :   try_control_builder.BeginTry(context);
    1710             :   {
    1711             :     ControlScopeForTryFinally scope(this, &try_control_builder, &commands);
    1712       36312 :     Visit(stmt->try_block());
    1713             :   }
    1714       36312 :   try_control_builder.EndTry();
    1715             : 
    1716             :   // Record fall-through and exception cases.
    1717       36312 :   commands.RecordFallThroughPath();
    1718       36312 :   try_control_builder.LeaveTry();
    1719       36312 :   try_control_builder.BeginHandler();
    1720             :   commands.RecordHandlerReThrowPath();
    1721             : 
    1722             :   // Pending message object is saved on entry.
    1723       36312 :   try_control_builder.BeginFinally();
    1724       36312 :   Register message = context;  // Reuse register.
    1725             : 
    1726             :   // Clear message object as we enter the finally block.
    1727       36312 :   builder()->LoadTheHole().SetPendingMessage().StoreAccumulatorInRegister(
    1728       36312 :       message);
    1729             : 
    1730             :   // Evaluate the finally-block.
    1731             :   BuildIncrementBlockCoverageCounterIfEnabled(stmt, SourceRangeKind::kFinally);
    1732       36312 :   Visit(stmt->finally_block());
    1733       36312 :   try_control_builder.EndFinally();
    1734             : 
    1735             :   // Pending message object is restored on exit.
    1736       36312 :   builder()->LoadAccumulatorWithRegister(message).SetPendingMessage();
    1737             : 
    1738             :   // Dynamic dispatch after the finally-block.
    1739       36312 :   commands.ApplyDeferredCommands();
    1740             :   BuildIncrementBlockCoverageCounterIfEnabled(stmt,
    1741             :                                               SourceRangeKind::kContinuation);
    1742       36312 : }
    1743             : 
    1744       12608 : void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
    1745             :   builder()->SetStatementPosition(stmt);
    1746        6304 :   builder()->Debugger();
    1747           0 : }
    1748             : 
    1749    11904950 : void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
    1750             :   DCHECK_EQ(expr->scope()->outer_scope(), current_scope());
    1751             :   uint8_t flags = CreateClosureFlags::Encode(
    1752    11904951 :       expr->pretenure(), closure_scope()->is_function_scope());
    1753     3968317 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    1754     3968319 :   FeedbackSlot slot = GetCachedCreateClosureSlot(expr);
    1755     7936632 :   builder()->CreateClosure(entry, feedback_index(slot), flags);
    1756     7936637 :   function_literals_.push_back(std::make_pair(expr, entry));
    1757     3968319 : }
    1758             : 
    1759      534917 : void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
    1760       59344 :   VisitDeclarations(expr->scope()->declarations());
    1761       59344 :   Register constructor = VisitForRegisterValue(expr->constructor());
    1762             :   {
    1763             :     RegisterAllocationScope register_scope(this);
    1764       59344 :     RegisterList args = register_allocator()->NewRegisterList(4);
    1765       59344 :     VisitForAccumulatorValueOrTheHole(expr->extends());
    1766             :     builder()
    1767       59344 :         ->StoreAccumulatorInRegister(args[0])
    1768       59344 :         .MoveRegister(constructor, args[1])
    1769       59344 :         .LoadLiteral(Smi::FromInt(expr->start_position()))
    1770       59344 :         .StoreAccumulatorInRegister(args[2])
    1771       59344 :         .LoadLiteral(Smi::FromInt(expr->end_position()))
    1772       59344 :         .StoreAccumulatorInRegister(args[3])
    1773       59344 :         .CallRuntime(Runtime::kDefineClass, args);
    1774             :   }
    1775       59344 :   Register prototype = register_allocator()->NewRegister();
    1776       59344 :   builder()->StoreAccumulatorInRegister(prototype);
    1777             : 
    1778       59344 :   if (FunctionLiteral::NeedsHomeObject(expr->constructor())) {
    1779             :     // Prototype is already in the accumulator.
    1780         821 :     FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
    1781             :     builder()->StoreHomeObjectProperty(constructor, feedback_index(slot),
    1782         821 :                                        language_mode());
    1783             :   }
    1784             : 
    1785       59344 :   VisitClassLiteralProperties(expr, constructor, prototype);
    1786       59344 :   BuildClassLiteralNameProperty(expr, constructor);
    1787       59344 :   builder()->CallRuntime(Runtime::kToFastProperties, constructor);
    1788             :   // Assign to class variable.
    1789       59344 :   if (expr->class_variable() != nullptr) {
    1790             :     DCHECK(expr->class_variable()->IsStackLocal() ||
    1791             :            expr->class_variable()->IsContextSlot());
    1792             :     BuildVariableAssignment(expr->class_variable(), Token::INIT,
    1793       53563 :                             HoleCheckMode::kElided);
    1794             :   }
    1795       59344 : }
    1796             : 
    1797      153793 : void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
    1798             :   CurrentScope current_scope(this, expr->scope());
    1799             :   DCHECK_NOT_NULL(expr->scope());
    1800       59344 :   if (expr->scope()->NeedsContext()) {
    1801       35105 :     BuildNewLocalBlockContext(expr->scope());
    1802       35105 :     ContextScope scope(this, expr->scope());
    1803       35105 :     BuildClassLiteral(expr);
    1804             :   } else {
    1805       24239 :     BuildClassLiteral(expr);
    1806             :   }
    1807       59344 : }
    1808             : 
    1809      515636 : void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
    1810             :                                                     Register constructor,
    1811      490181 :                                                     Register prototype) {
    1812             :   RegisterAllocationScope register_scope(this);
    1813       59344 :   RegisterList args = register_allocator()->NewRegisterList(4);
    1814      178032 :   Register receiver = args[0], key = args[1], value = args[2], attr = args[3];
    1815             : 
    1816             :   bool attr_assigned = false;
    1817             :   Register old_receiver = Register::invalid_value();
    1818             : 
    1819             :   // Create nodes to store method values into the literal.
    1820      912584 :   for (int i = 0; i < expr->properties()->length(); i++) {
    1821     1190844 :     ClassLiteral::Property* property = expr->properties()->at(i);
    1822             : 
    1823             :     // Set-up receiver.
    1824      396948 :     Register new_receiver = property->is_static() ? constructor : prototype;
    1825      396948 :     if (new_receiver != old_receiver) {
    1826       45368 :       builder()->MoveRegister(new_receiver, receiver);
    1827             :       old_receiver = new_receiver;
    1828             :     }
    1829             : 
    1830      396948 :     BuildLoadPropertyKey(property, key);
    1831      793896 :     if (property->is_static() && property->is_computed_name()) {
    1832             :       // The static prototype property is read only. We handle the non computed
    1833             :       // property name case in the parser. Since this is the only case where we
    1834             :       // need to check for an own read only property we special case this so we
    1835             :       // do not need to do this for every property.
    1836             :       BytecodeLabel done;
    1837             :       builder()
    1838        2798 :           ->LoadLiteral(ast_string_constants()->prototype_string())
    1839        1399 :           .CompareOperation(Token::Value::EQ_STRICT, key)
    1840        1399 :           .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done)
    1841        1399 :           .CallRuntime(Runtime::kThrowStaticPrototypeError)
    1842        1399 :           .Bind(&done);
    1843             :     }
    1844             : 
    1845             :     VisitForRegisterValue(property->value(), value);
    1846      396948 :     VisitSetHomeObject(value, receiver, property);
    1847             : 
    1848      396948 :     if (!attr_assigned) {
    1849             :       builder()
    1850       45067 :           ->LoadLiteral(Smi::FromInt(DONT_ENUM))
    1851       45067 :           .StoreAccumulatorInRegister(attr);
    1852             :       attr_assigned = true;
    1853             :     }
    1854             : 
    1855      396948 :     switch (property->kind()) {
    1856             :       case ClassLiteral::Property::METHOD: {
    1857             :         DataPropertyInLiteralFlags flags = DataPropertyInLiteralFlag::kDontEnum;
    1858      388365 :         if (property->NeedsSetFunctionName()) {
    1859             :           flags |= DataPropertyInLiteralFlag::kSetFunctionName;
    1860             :         }
    1861             : 
    1862             :         FeedbackSlot slot =
    1863      388365 :             feedback_spec()->AddStoreDataPropertyInLiteralICSlot();
    1864             :         builder()
    1865      388365 :             ->LoadAccumulatorWithRegister(value)
    1866             :             .StoreDataPropertyInLiteral(receiver, key, flags,
    1867      388365 :                                         feedback_index(slot));
    1868             :         break;
    1869             :       }
    1870             :       case ClassLiteral::Property::GETTER: {
    1871        5712 :         builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked, args);
    1872        5712 :         break;
    1873             :       }
    1874             :       case ClassLiteral::Property::SETTER: {
    1875        2871 :         builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, args);
    1876        2871 :         break;
    1877             :       }
    1878             :       case ClassLiteral::Property::FIELD: {
    1879           0 :         UNREACHABLE();
    1880             :         break;
    1881             :       }
    1882             :     }
    1883       59344 :   }
    1884       59344 : }
    1885             : 
    1886      118601 : void BytecodeGenerator::BuildClassLiteralNameProperty(ClassLiteral* expr,
    1887       53854 :                                                       Register literal) {
    1888      118601 :   if (!expr->has_name_static_property() &&
    1889       59257 :       expr->constructor()->has_shared_name()) {
    1890             :     Runtime::FunctionId runtime_id =
    1891             :         expr->has_static_computed_names()
    1892             :             ? Runtime::kInstallClassNameAccessorWithCheck
    1893       53854 :             : Runtime::kInstallClassNameAccessor;
    1894       53854 :     builder()->CallRuntime(runtime_id, literal);
    1895             :   }
    1896       59344 : }
    1897             : 
    1898        1678 : void BytecodeGenerator::VisitNativeFunctionLiteral(
    1899        3356 :     NativeFunctionLiteral* expr) {
    1900        1678 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    1901        1678 :   FeedbackSlot slot = feedback_spec()->AddCreateClosureSlot();
    1902        1678 :   builder()->CreateClosure(entry, feedback_index(slot), NOT_TENURED);
    1903        3356 :   native_function_literals_.push_back(std::make_pair(expr, entry));
    1904        1678 : }
    1905             : 
    1906        3862 : void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
    1907        1931 :   VisitBlock(expr->block());
    1908        1931 :   VisitVariableProxy(expr->result());
    1909        1931 : }
    1910             : 
    1911      334568 : void BytecodeGenerator::VisitConditional(Conditional* expr) {
    1912             :   ConditionalControlFlowBuilder conditional_builder(
    1913       95862 :       builder(), block_coverage_builder_, expr);
    1914             : 
    1915       47931 :   if (expr->condition()->ToBooleanIsTrue()) {
    1916             :     // Generate then block unconditionally as always true.
    1917         241 :     conditional_builder.Then();
    1918         241 :     VisitForAccumulatorValue(expr->then_expression());
    1919       47690 :   } else if (expr->condition()->ToBooleanIsFalse()) {
    1920             :     // Generate else block unconditionally if it exists.
    1921         113 :     conditional_builder.Else();
    1922         113 :     VisitForAccumulatorValue(expr->else_expression());
    1923             :   } else {
    1924             :     VisitForTest(expr->condition(), conditional_builder.then_labels(),
    1925       47577 :                  conditional_builder.else_labels(), TestFallthrough::kThen);
    1926             : 
    1927       47577 :     conditional_builder.Then();
    1928       47577 :     VisitForAccumulatorValue(expr->then_expression());
    1929       47577 :     conditional_builder.JumpToEnd();
    1930             : 
    1931       47577 :     conditional_builder.Else();
    1932       47577 :     VisitForAccumulatorValue(expr->else_expression());
    1933       47931 :   }
    1934       47931 : }
    1935             : 
    1936    17637644 : void BytecodeGenerator::VisitLiteral(Literal* expr) {
    1937     9310551 :   if (!execution_result()->IsEffect()) {
    1938     7996440 :     const AstValue* raw_value = expr->raw_value();
    1939     7996443 :     builder()->LoadLiteral(raw_value);
    1940    15873236 :     if (raw_value->IsTrue() || raw_value->IsFalse()) {
    1941             :       execution_result()->SetResultIsBoolean();
    1942             :     }
    1943             :   }
    1944     9310548 : }
    1945             : 
    1946      115174 : void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
    1947             :   // Materialize a regular expression literal.
    1948             :   builder()->CreateRegExpLiteral(
    1949       57587 :       expr->raw_pattern(), feedback_index(feedback_spec()->AddLiteralSlot()),
    1950       57587 :       expr->flags());
    1951       57587 : }
    1952             : 
    1953     1742701 : void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
    1954             :   // Fast path for the empty object literal which doesn't need an
    1955             :   // AllocationSite.
    1956     3619334 :   if (expr->IsEmptyObjectLiteral()) {
    1957             :     DCHECK(expr->IsFastCloningSupported());
    1958       40224 :     builder()->CreateEmptyObjectLiteral();
    1959      344009 :     return;
    1960             :   }
    1961             : 
    1962      263561 :   int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
    1963             :   // Deep-copy the literal boilerplate.
    1964             :   uint8_t flags = CreateObjectLiteralFlags::Encode(
    1965      263561 :       expr->ComputeFlags(), expr->IsFastCloningSupported());
    1966             : 
    1967      263561 :   Register literal = register_allocator()->NewRegister();
    1968             :   size_t entry;
    1969             :   // If constant properties is an empty fixed array, use a cached empty fixed
    1970             :   // array to ensure it's only added to the constant pool once.
    1971      263561 :   if (expr->properties_count() == 0) {
    1972        6863 :     entry = builder()->EmptyFixedArrayConstantPoolEntry();
    1973             :   } else {
    1974      256698 :     entry = builder()->AllocateDeferredConstantPoolEntry();
    1975      513396 :     object_literals_.push_back(std::make_pair(expr, entry));
    1976             :   }
    1977             :   // TODO(cbruni): Directly generate runtime call for literals we cannot
    1978             :   // optimize once the CreateShallowObjectLiteral stub is in sync with the TF
    1979             :   // optimizations.
    1980      527122 :   builder()->CreateObjectLiteral(entry, literal_index, flags, literal);
    1981             : 
    1982             :   // Store computed values into the literal.
    1983             :   int property_index = 0;
    1984             :   AccessorTable accessor_table(zone());
    1985     5305431 :   for (; property_index < expr->properties()->length(); property_index++) {
    1986     2879075 :     ObjectLiteral::Property* property = expr->properties()->at(property_index);
    1987     3537399 :     if (property->is_computed_name()) break;
    1988     4685692 :     if (property->IsCompileTimeValue()) continue;
    1989             : 
    1990             :     RegisterAllocationScope inner_register_scope(this);
    1991      684146 :     Literal* key = property->key()->AsLiteral();
    1992      356178 :     switch (property->kind()) {
    1993             :       case ObjectLiteral::Property::SPREAD:
    1994             :       case ObjectLiteral::Property::CONSTANT:
    1995           0 :         UNREACHABLE();
    1996             :       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
    1997             :         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
    1998             :       // Fall through.
    1999             :       case ObjectLiteral::Property::COMPUTED: {
    2000             :         // It is safe to use [[Put]] here because the boilerplate already
    2001             :         // contains computed properties with an uninitialized value.
    2002      328695 :         if (key->IsStringLiteral()) {
    2003             :           DCHECK(key->IsPropertyName());
    2004      328114 :           if (property->emit_store()) {
    2005      327968 :             VisitForAccumulatorValue(property->value());
    2006      327968 :             FeedbackSlot slot = feedback_spec()->AddStoreOwnICSlot();
    2007      327968 :             if (FunctionLiteral::NeedsHomeObject(property->value())) {
    2008             :               RegisterAllocationScope register_scope(this);
    2009         464 :               Register value = register_allocator()->NewRegister();
    2010         464 :               builder()->StoreAccumulatorInRegister(value);
    2011             :               builder()->StoreNamedOwnProperty(
    2012         928 :                   literal, key->AsRawPropertyName(), feedback_index(slot));
    2013         464 :               VisitSetHomeObject(value, literal, property);
    2014             :             } else {
    2015             :               builder()->StoreNamedOwnProperty(
    2016      655008 :                   literal, key->AsRawPropertyName(), feedback_index(slot));
    2017             :             }
    2018             :           } else {
    2019         146 :             VisitForEffect(property->value());
    2020             :           }
    2021             :         } else {
    2022         581 :           RegisterList args = register_allocator()->NewRegisterList(4);
    2023             : 
    2024         581 :           builder()->MoveRegister(literal, args[0]);
    2025             :           VisitForRegisterValue(property->key(), args[1]);
    2026             :           VisitForRegisterValue(property->value(), args[2]);
    2027         581 :           if (property->emit_store()) {
    2028             :             builder()
    2029         546 :                 ->LoadLiteral(Smi::FromEnum(LanguageMode::kSloppy))
    2030         546 :                 .StoreAccumulatorInRegister(args[3])
    2031         546 :                 .CallRuntime(Runtime::kSetProperty, args);
    2032         546 :             Register value = args[2];
    2033         546 :             VisitSetHomeObject(value, literal, property);
    2034             :           }
    2035             :         }
    2036             :         break;
    2037             :       }
    2038             :       case ObjectLiteral::Property::PROTOTYPE: {
    2039             :         // __proto__:null is handled by CreateObjectLiteral.
    2040       22747 :         if (property->IsNullPrototype()) break;
    2041             :         DCHECK(property->emit_store());
    2042             :         DCHECK(!property->NeedsSetFunctionName());
    2043        1080 :         RegisterList args = register_allocator()->NewRegisterList(2);
    2044        1080 :         builder()->MoveRegister(literal, args[0]);
    2045             :         VisitForRegisterValue(property->value(), args[1]);
    2046        1080 :         builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
    2047        1080 :         break;
    2048             :       }
    2049             :       case ObjectLiteral::Property::GETTER:
    2050        2829 :         if (property->emit_store()) {
    2051        2751 :           accessor_table.lookup(key)->second->getter = property;
    2052             :         }
    2053             :         break;
    2054             :       case ObjectLiteral::Property::SETTER:
    2055        1907 :         if (property->emit_store()) {
    2056        1841 :           accessor_table.lookup(key)->second->setter = property;
    2057             :         }
    2058             :         break;
    2059             :     }
    2060      356178 :   }
    2061             : 
    2062             :   // Define accessors, using only a single call to the runtime for each pair of
    2063             :   // corresponding getters and setters.
    2064      531122 :   for (AccessorTable::Iterator it = accessor_table.begin();
    2065             :        it != accessor_table.end(); ++it) {
    2066             :     RegisterAllocationScope inner_register_scope(this);
    2067        4000 :     RegisterList args = register_allocator()->NewRegisterList(5);
    2068        4000 :     builder()->MoveRegister(literal, args[0]);
    2069        4000 :     VisitForRegisterValue(it->first, args[1]);
    2070        4000 :     VisitObjectLiteralAccessor(literal, it->second->getter, args[2]);
    2071        4000 :     VisitObjectLiteralAccessor(literal, it->second->setter, args[3]);
    2072             :     builder()
    2073        4000 :         ->LoadLiteral(Smi::FromInt(NONE))
    2074        4000 :         .StoreAccumulatorInRegister(args[4])
    2075        4000 :         .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, args);
    2076        4000 :   }
    2077             : 
    2078             :   // Object literals have two parts. The "static" part on the left contains no
    2079             :   // computed property names, and so we can compute its map ahead of time; see
    2080             :   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
    2081             :   // with the first computed property name and continues with all properties to
    2082             :   // its right. All the code from above initializes the static component of the
    2083             :   // object literal, and arranges for the map of the result to reflect the
    2084             :   // static order in which the keys appear. For the dynamic properties, we
    2085             :   // compile them into a series of "SetOwnProperty" runtime calls. This will
    2086             :   // preserve insertion order.
    2087      271423 :   for (; property_index < expr->properties()->length(); property_index++) {
    2088        4213 :     ObjectLiteral::Property* property = expr->properties()->at(property_index);
    2089             :     RegisterAllocationScope inner_register_scope(this);
    2090             : 
    2091        3931 :     if (property->IsPrototype()) {
    2092             :       // __proto__:null is handled by CreateObjectLiteral.
    2093          46 :       if (property->IsNullPrototype()) continue;
    2094             :       DCHECK(property->emit_store());
    2095             :       DCHECK(!property->NeedsSetFunctionName());
    2096          40 :       RegisterList args = register_allocator()->NewRegisterList(2);
    2097          40 :       builder()->MoveRegister(literal, args[0]);
    2098        3925 :       VisitForRegisterValue(property->value(), args[1]);
    2099          40 :       builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
    2100          40 :       continue;
    2101             :     }
    2102             : 
    2103        3885 :     switch (property->kind()) {
    2104             :       case ObjectLiteral::Property::CONSTANT:
    2105             :       case ObjectLiteral::Property::COMPUTED:
    2106             :       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
    2107        3403 :         Register key = register_allocator()->NewRegister();
    2108        3403 :         BuildLoadPropertyKey(property, key);
    2109        3403 :         Register value = VisitForRegisterValue(property->value());
    2110        3403 :         VisitSetHomeObject(value, literal, property);
    2111             : 
    2112             :         DataPropertyInLiteralFlags data_property_flags =
    2113             :             DataPropertyInLiteralFlag::kNoFlags;
    2114        3403 :         if (property->NeedsSetFunctionName()) {
    2115             :           data_property_flags |= DataPropertyInLiteralFlag::kSetFunctionName;
    2116             :         }
    2117             : 
    2118             :         FeedbackSlot slot =
    2119        3403 :             feedback_spec()->AddStoreDataPropertyInLiteralICSlot();
    2120             :         builder()
    2121        3403 :             ->LoadAccumulatorWithRegister(value)
    2122             :             .StoreDataPropertyInLiteral(literal, key, data_property_flags,
    2123        3403 :                                         feedback_index(slot));
    2124             :         break;
    2125             :       }
    2126             :       case ObjectLiteral::Property::GETTER:
    2127             :       case ObjectLiteral::Property::SETTER: {
    2128         282 :         RegisterList args = register_allocator()->NewRegisterList(4);
    2129         282 :         builder()->MoveRegister(literal, args[0]);
    2130         282 :         BuildLoadPropertyKey(property, args[1]);
    2131             :         VisitForRegisterValue(property->value(), args[2]);
    2132         282 :         VisitSetHomeObject(args[2], literal, property);
    2133             :         builder()
    2134         282 :             ->LoadLiteral(Smi::FromInt(NONE))
    2135         282 :             .StoreAccumulatorInRegister(args[3]);
    2136             :         Runtime::FunctionId function_id =
    2137             :             property->kind() == ObjectLiteral::Property::GETTER
    2138             :                 ? Runtime::kDefineGetterPropertyUnchecked
    2139         282 :                 : Runtime::kDefineSetterPropertyUnchecked;
    2140         282 :         builder()->CallRuntime(function_id, args);
    2141             :         break;
    2142             :       }
    2143             :       case ObjectLiteral::Property::SPREAD: {
    2144         200 :         RegisterList args = register_allocator()->NewRegisterList(2);
    2145         200 :         builder()->MoveRegister(literal, args[0]);
    2146             :         VisitForRegisterValue(property->value(), args[1]);
    2147         200 :         builder()->CallRuntime(Runtime::kCopyDataProperties, args);
    2148             :         break;
    2149             :       }
    2150             :       case ObjectLiteral::Property::PROTOTYPE:
    2151           0 :         UNREACHABLE();  // Handled specially above.
    2152             :         break;
    2153             :     }
    2154        3885 :   }
    2155             : 
    2156      263561 :   builder()->LoadAccumulatorWithRegister(literal);
    2157             : }
    2158             : 
    2159     1308345 : void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
    2160             :   // Deep-copy the literal boilerplate.
    2161      248665 :   int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
    2162     8292316 :   if (expr->is_empty()) {
    2163             :     // Empty array literal fast-path.
    2164             :     DCHECK(expr->IsFastCloningSupported());
    2165      137206 :     builder()->CreateEmptyArrayLiteral(literal_index);
    2166      385871 :     return;
    2167             :   }
    2168             : 
    2169             :   uint8_t flags = CreateArrayLiteralFlags::Encode(
    2170      111459 :       expr->IsFastCloningSupported(), expr->ComputeFlags());
    2171      111459 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    2172      222918 :   builder()->CreateArrayLiteral(entry, literal_index, flags);
    2173      222918 :   array_literals_.push_back(std::make_pair(expr, entry));
    2174             : 
    2175             :   Register index, literal;
    2176             : 
    2177             :   // We'll reuse the same literal slot for all of the non-constant
    2178             :   // subexpressions that use a keyed store IC.
    2179             : 
    2180             :   // Evaluate all the non-constant subexpressions and store them into the
    2181             :   // newly cloned array.
    2182             :   bool literal_in_accumulator = true;
    2183             :   FeedbackSlot slot;
    2184    16087302 :   for (int array_index = 0; array_index < expr->values()->length();
    2185             :        array_index++) {
    2186     7932192 :     Expression* subexpr = expr->values()->at(array_index);
    2187     7932192 :     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
    2188             :     DCHECK(!subexpr->IsSpread());
    2189             : 
    2190      285376 :     if (literal_in_accumulator) {
    2191       64402 :       index = register_allocator()->NewRegister();
    2192       64402 :       literal = register_allocator()->NewRegister();
    2193       64402 :       builder()->StoreAccumulatorInRegister(literal);
    2194             :       literal_in_accumulator = false;
    2195             :     }
    2196      285376 :     if (slot.IsInvalid()) {
    2197       64402 :       slot = feedback_spec()->AddKeyedStoreICSlot(language_mode());
    2198             :     }
    2199             : 
    2200             :     builder()
    2201      285376 :         ->LoadLiteral(Smi::FromInt(array_index))
    2202      285376 :         .StoreAccumulatorInRegister(index);
    2203      285376 :     VisitForAccumulatorValue(subexpr);
    2204             :     builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
    2205      285376 :                                   language_mode());
    2206             :   }
    2207             : 
    2208      111459 :   if (!literal_in_accumulator) {
    2209             :     // Restore literal array into accumulator.
    2210       64402 :     builder()->LoadAccumulatorWithRegister(literal);
    2211             :   }
    2212             : }
    2213             : 
    2214    30352524 : void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
    2215             :   builder()->SetExpressionPosition(proxy);
    2216    10117508 :   BuildVariableLoad(proxy->var(), proxy->hole_check_mode());
    2217    10117509 : }
    2218             : 
    2219    31312784 : void BytecodeGenerator::BuildVariableLoad(Variable* variable,
    2220             :                                           HoleCheckMode hole_check_mode,
    2221    26126140 :                                           TypeofMode typeof_mode) {
    2222    11699929 :   switch (variable->location()) {
    2223             :     case VariableLocation::LOCAL: {
    2224     3585893 :       Register source(builder()->Local(variable->index()));
    2225             :       // We need to load the variable into the accumulator, even when in a
    2226             :       // VisitForRegisterScope, in order to avoid register aliasing if
    2227             :       // subsequent expressions assign to the same variable.
    2228     3585895 :       builder()->LoadAccumulatorWithRegister(source);
    2229     3585895 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2230        2470 :         BuildThrowIfHole(variable);
    2231             :       }
    2232             :       break;
    2233             :     }
    2234             :     case VariableLocation::PARAMETER: {
    2235             :       Register source;
    2236     2485107 :       if (variable->IsReceiver()) {
    2237      396365 :         source = builder()->Receiver();
    2238             :       } else {
    2239     2088742 :         source = builder()->Parameter(variable->index());
    2240             :       }
    2241             :       // We need to load the variable into the accumulator, even when in a
    2242             :       // VisitForRegisterScope, in order to avoid register aliasing if
    2243             :       // subsequent expressions assign to the same variable.
    2244     2485107 :       builder()->LoadAccumulatorWithRegister(source);
    2245     2485108 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2246       16267 :         BuildThrowIfHole(variable);
    2247             :       }
    2248             :       break;
    2249             :     }
    2250             :     case VariableLocation::UNALLOCATED: {
    2251             :       // The global identifier "undefined" is immutable. Everything
    2252             :       // else could be reassigned. For performance, we do a pointer comparison
    2253             :       // rather than checking if the raw_name is really "undefined".
    2254     2507969 :       if (variable->raw_name() == ast_string_constants()->undefined_string()) {
    2255       76524 :         builder()->LoadUndefined();
    2256             :       } else {
    2257     2431445 :         FeedbackSlot slot = GetCachedLoadGlobalICSlot(typeof_mode, variable);
    2258             :         builder()->LoadGlobal(variable->raw_name(), feedback_index(slot),
    2259     2431445 :                               typeof_mode);
    2260             :       }
    2261             :       break;
    2262             :     }
    2263             :     case VariableLocation::CONTEXT: {
    2264     2738083 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2265             :       ContextScope* context = execution_context()->Previous(depth);
    2266             :       Register context_reg;
    2267     2738083 :       if (context) {
    2268     2710060 :         context_reg = context->reg();
    2269             :         depth = 0;
    2270             :       } else {
    2271       28023 :         context_reg = execution_context()->reg();
    2272             :       }
    2273             : 
    2274             :       BytecodeArrayBuilder::ContextSlotMutability immutable =
    2275             :           (variable->maybe_assigned() == kNotAssigned)
    2276             :               ? BytecodeArrayBuilder::kImmutableSlot
    2277     2738083 :               : BytecodeArrayBuilder::kMutableSlot;
    2278             : 
    2279             :       builder()->LoadContextSlot(context_reg, variable->index(), depth,
    2280     2738083 :                                  immutable);
    2281     2738082 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2282      170472 :         BuildThrowIfHole(variable);
    2283             :       }
    2284             :       break;
    2285             :     }
    2286             :     case VariableLocation::LOOKUP: {
    2287      381402 :       switch (variable->mode()) {
    2288             :         case DYNAMIC_LOCAL: {
    2289        7664 :           Variable* local_variable = variable->local_if_not_shadowed();
    2290             :           int depth =
    2291        3832 :               execution_context()->ContextChainDepth(local_variable->scope());
    2292             :           builder()->LoadLookupContextSlot(variable->raw_name(), typeof_mode,
    2293        3832 :                                            local_variable->index(), depth);
    2294        3832 :           if (hole_check_mode == HoleCheckMode::kRequired) {
    2295        1768 :             BuildThrowIfHole(variable);
    2296             :           }
    2297             :           break;
    2298             :         }
    2299             :         case DYNAMIC_GLOBAL: {
    2300             :           int depth =
    2301      365759 :               closure_scope()->ContextChainLengthUntilOutermostSloppyEval();
    2302      365759 :           FeedbackSlot slot = GetCachedLoadGlobalICSlot(typeof_mode, variable);
    2303             :           builder()->LoadLookupGlobalSlot(variable->raw_name(), typeof_mode,
    2304      365759 :                                           feedback_index(slot), depth);
    2305             :           break;
    2306             :         }
    2307             :         default:
    2308       11811 :           builder()->LoadLookupSlot(variable->raw_name(), typeof_mode);
    2309             :       }
    2310             :       break;
    2311             :     }
    2312             :     case VariableLocation::MODULE: {
    2313        1479 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2314        1479 :       builder()->LoadModuleVariable(variable->index(), depth);
    2315        1479 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2316         881 :         BuildThrowIfHole(variable);
    2317             :       }
    2318             :       break;
    2319             :     }
    2320             :   }
    2321    11699930 : }
    2322             : 
    2323     1481524 : void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
    2324             :     Variable* variable, HoleCheckMode hole_check_mode, TypeofMode typeof_mode) {
    2325             :   ValueResultScope accumulator_result(this);
    2326     1481524 :   BuildVariableLoad(variable, hole_check_mode, typeof_mode);
    2327     1481524 : }
    2328             : 
    2329    12933715 : void BytecodeGenerator::BuildReturn(int source_position) {
    2330     2586726 :   if (FLAG_trace) {
    2331             :     RegisterAllocationScope register_scope(this);
    2332           0 :     Register result = register_allocator()->NewRegister();
    2333             :     // Runtime returns {result} value, preserving accumulator.
    2334           0 :     builder()->StoreAccumulatorInRegister(result).CallRuntime(
    2335           0 :         Runtime::kTraceExit, result);
    2336             :   }
    2337     2586726 :   if (info()->collect_type_profile()) {
    2338         170 :     builder()->CollectTypeProfile(info()->literal()->return_position());
    2339             :   }
    2340     5173452 :   builder()->SetReturnPosition(source_position, info()->literal());
    2341     2586726 :   builder()->Return();
    2342     2586730 : }
    2343             : 
    2344       11042 : void BytecodeGenerator::BuildAsyncReturn(int source_position) {
    2345             :   RegisterAllocationScope register_scope(this);
    2346             : 
    2347        5208 :   if (IsAsyncGeneratorFunction(info()->literal()->kind())) {
    2348         989 :     RegisterList args = register_allocator()->NewRegisterList(3);
    2349             :     builder()
    2350         989 :         ->MoveRegister(generator_object(), args[0])  // generator
    2351         989 :         .StoreAccumulatorInRegister(args[1])         // value
    2352         989 :         .LoadTrue()
    2353         989 :         .StoreAccumulatorInRegister(args[2])  // done
    2354         989 :         .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args);
    2355             :   } else {
    2356             :     DCHECK(IsAsyncFunction(info()->literal()->kind()));
    2357        1615 :     RegisterList args = register_allocator()->NewRegisterList(2);
    2358        1615 :     Register promise = args[0];
    2359        1615 :     Register return_value = args[1];
    2360        1615 :     builder()->StoreAccumulatorInRegister(return_value);
    2361             : 
    2362             :     Variable* var_promise = closure_scope()->promise_var();
    2363             :     DCHECK_NOT_NULL(var_promise);
    2364        1615 :     BuildVariableLoad(var_promise, HoleCheckMode::kElided);
    2365             :     builder()
    2366        1615 :         ->StoreAccumulatorInRegister(promise)
    2367        1615 :         .CallJSRuntime(Context::PROMISE_RESOLVE_INDEX, args)
    2368        1615 :         .LoadAccumulatorWithRegister(promise);
    2369             :   }
    2370             : 
    2371        2604 :   BuildReturn(source_position);
    2372        2604 : }
    2373             : 
    2374       36231 : void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); }
    2375             : 
    2376      452116 : void BytecodeGenerator::BuildThrowIfHole(Variable* variable) {
    2377      226058 :   if (variable->is_this()) {
    2378             :     DCHECK(variable->mode() == CONST);
    2379       16387 :     builder()->ThrowSuperNotCalledIfHole();
    2380             :   } else {
    2381      209671 :     builder()->ThrowReferenceErrorIfHole(variable->raw_name());
    2382             :   }
    2383      226058 : }
    2384             : 
    2385       36315 : void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
    2386        2115 :                                                             Token::Value op) {
    2387       38430 :   if (variable->is_this() && variable->mode() == CONST && op == Token::INIT) {
    2388             :     // Perform an initialization check for 'this'. 'this' variable is the
    2389             :     // only variable able to trigger bind operations outside the TDZ
    2390             :     // via 'super' calls.
    2391        2115 :     builder()->ThrowSuperAlreadyCalledIfNotHole();
    2392             :   } else {
    2393             :     // Perform an initialization check for let/const declared variables.
    2394             :     // E.g. let x = (x = 20); is not allowed.
    2395             :     DCHECK(IsLexicalVariableMode(variable->mode()));
    2396       34200 :     BuildThrowIfHole(variable);
    2397             :   }
    2398       36315 : }
    2399             : 
    2400     5583038 : void BytecodeGenerator::BuildVariableAssignment(
    2401    12762731 :     Variable* variable, Token::Value op, HoleCheckMode hole_check_mode,
    2402     8776291 :     LookupHoistingMode lookup_hoisting_mode) {
    2403             :   VariableMode mode = variable->mode();
    2404             :   RegisterAllocationScope assignment_register_scope(this);
    2405             :   BytecodeLabel end_label;
    2406     5583038 :   switch (variable->location()) {
    2407             :     case VariableLocation::PARAMETER:
    2408             :     case VariableLocation::LOCAL: {
    2409             :       Register destination;
    2410     2893984 :       if (VariableLocation::PARAMETER == variable->location()) {
    2411       32248 :         if (variable->IsReceiver()) {
    2412        2043 :           destination = builder()->Receiver();
    2413             :         } else {
    2414       30205 :           destination = builder()->Parameter(variable->index());
    2415             :         }
    2416             :       } else {
    2417     2861736 :         destination = builder()->Local(variable->index());
    2418             :       }
    2419             : 
    2420     2893985 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2421             :         // Load destination to check for hole.
    2422        4640 :         Register value_temp = register_allocator()->NewRegister();
    2423             :         builder()
    2424        4640 :             ->StoreAccumulatorInRegister(value_temp)
    2425        4640 :             .LoadAccumulatorWithRegister(destination);
    2426             : 
    2427        4640 :         BuildHoleCheckForVariableAssignment(variable, op);
    2428        4640 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2429             :       }
    2430             : 
    2431     2893985 :       if (mode != CONST || op == Token::INIT) {
    2432     2889094 :         builder()->StoreAccumulatorInRegister(destination);
    2433        4891 :       } else if (variable->throw_on_const_assignment(language_mode())) {
    2434        4858 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2435             :       }
    2436             :       break;
    2437             :     }
    2438             :     case VariableLocation::UNALLOCATED: {
    2439             :       // TODO(ishell): consider using FeedbackSlotCache for variables here.
    2440             :       FeedbackSlot slot =
    2441     1064785 :           feedback_spec()->AddStoreGlobalICSlot(language_mode());
    2442             :       builder()->StoreGlobal(variable->raw_name(), feedback_index(slot),
    2443     1064785 :                              language_mode());
    2444             :       break;
    2445             :     }
    2446             :     case VariableLocation::CONTEXT: {
    2447     1558542 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2448             :       ContextScope* context = execution_context()->Previous(depth);
    2449             :       Register context_reg;
    2450             : 
    2451     1558542 :       if (context) {
    2452     1549696 :         context_reg = context->reg();
    2453             :         depth = 0;
    2454             :       } else {
    2455        8846 :         context_reg = execution_context()->reg();
    2456             :       }
    2457             : 
    2458     1558542 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2459             :         // Load destination to check for hole.
    2460       31591 :         Register value_temp = register_allocator()->NewRegister();
    2461             :         builder()
    2462       31591 :             ->StoreAccumulatorInRegister(value_temp)
    2463             :             .LoadContextSlot(context_reg, variable->index(), depth,
    2464       31591 :                              BytecodeArrayBuilder::kMutableSlot);
    2465             : 
    2466       31591 :         BuildHoleCheckForVariableAssignment(variable, op);
    2467       31591 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2468             :       }
    2469             : 
    2470     1558542 :       if (mode != CONST || op == Token::INIT) {
    2471     1530452 :         builder()->StoreContextSlot(context_reg, variable->index(), depth);
    2472       28090 :       } else if (variable->throw_on_const_assignment(language_mode())) {
    2473       28068 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2474             :       }
    2475             :       break;
    2476             :     }
    2477             :     case VariableLocation::LOOKUP: {
    2478             :       builder()->StoreLookupSlot(variable->raw_name(), language_mode(),
    2479       30935 :                                  lookup_hoisting_mode);
    2480       30935 :       break;
    2481             :     }
    2482             :     case VariableLocation::MODULE: {
    2483             :       DCHECK(IsDeclaredVariableMode(mode));
    2484             : 
    2485       34792 :       if (mode == CONST && op != Token::INIT) {
    2486         132 :         builder()->CallRuntime(Runtime::kThrowConstAssignError);
    2487         132 :         break;
    2488             :       }
    2489             : 
    2490             :       // If we don't throw above, we know that we're dealing with an
    2491             :       // export because imports are const and we do not generate initializing
    2492             :       // assignments for them.
    2493             :       DCHECK(variable->IsExport());
    2494             : 
    2495       34660 :       int depth = execution_context()->ContextChainDepth(variable->scope());
    2496       34660 :       if (hole_check_mode == HoleCheckMode::kRequired) {
    2497          84 :         Register value_temp = register_allocator()->NewRegister();
    2498             :         builder()
    2499          84 :             ->StoreAccumulatorInRegister(value_temp)
    2500          84 :             .LoadModuleVariable(variable->index(), depth);
    2501          84 :         BuildHoleCheckForVariableAssignment(variable, op);
    2502          84 :         builder()->LoadAccumulatorWithRegister(value_temp);
    2503             :       }
    2504       34660 :       builder()->StoreModuleVariable(variable->index(), depth);
    2505       34660 :       break;
    2506             :     }
    2507     5583039 :   }
    2508     5583039 : }
    2509             : 
    2510    38555807 : void BytecodeGenerator::VisitAssignment(Assignment* expr) {
    2511             :   DCHECK(expr->target()->IsValidReferenceExpression() ||
    2512             :          (expr->op() == Token::INIT && expr->target()->IsVariableProxy() &&
    2513             :           expr->target()->AsVariableProxy()->is_this()));
    2514             :   Register object, key;
    2515             :   RegisterList super_property_args;
    2516             :   const AstRawString* name;
    2517             : 
    2518             :   // Left-hand side can only be a property, a global or a variable slot.
    2519     9807430 :   Property* property = expr->target()->AsProperty();
    2520     6628060 :   LhsKind assign_type = Property::GetAssignType(property);
    2521             : 
    2522             :   // Evaluate LHS expression.
    2523     6628062 :   switch (assign_type) {
    2524             :     case VARIABLE:
    2525             :       // Nothing to do to evaluate variable assignment LHS.
    2526             :       break;
    2527             :     case NAMED_PROPERTY: {
    2528     1529450 :       object = VisitForRegisterValue(property->obj());
    2529     3058900 :       name = property->key()->AsLiteral()->AsRawPropertyName();
    2530     1529450 :       break;
    2531             :     }
    2532             :     case KEYED_PROPERTY: {
    2533       59687 :       object = VisitForRegisterValue(property->obj());
    2534       59687 :       key = VisitForRegisterValue(property->key());
    2535       59687 :       break;
    2536             :     }
    2537             :     case NAMED_SUPER_PROPERTY: {
    2538         217 :       super_property_args = register_allocator()->NewRegisterList(4);
    2539         434 :       SuperPropertyReference* super_property =
    2540         217 :           property->obj()->AsSuperPropertyReference();
    2541             :       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
    2542             :       VisitForRegisterValue(super_property->home_object(),
    2543             :                             super_property_args[1]);
    2544             :       builder()
    2545         651 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    2546         217 :           .StoreAccumulatorInRegister(super_property_args[2]);
    2547         217 :       break;
    2548             :     }
    2549             :     case KEYED_SUPER_PROPERTY: {
    2550         331 :       super_property_args = register_allocator()->NewRegisterList(4);
    2551         662 :       SuperPropertyReference* super_property =
    2552         331 :           property->obj()->AsSuperPropertyReference();
    2553             :       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
    2554             :       VisitForRegisterValue(super_property->home_object(),
    2555             :                             super_property_args[1]);
    2556             :       VisitForRegisterValue(property->key(), super_property_args[2]);
    2557             :       break;
    2558             :     }
    2559             :   }
    2560             : 
    2561             :   // Evaluate the value and potentially handle compound assignments by loading
    2562             :   // the left-hand side value and performing a binary operation.
    2563     6628062 :   if (expr->IsCompoundAssignment()) {
    2564      100697 :     switch (assign_type) {
    2565             :       case VARIABLE: {
    2566      297840 :         VariableProxy* proxy = expr->target()->AsVariableProxy();
    2567       99280 :         BuildVariableLoad(proxy->var(), proxy->hole_check_mode());
    2568       99280 :         break;
    2569             :       }
    2570             :       case NAMED_PROPERTY: {
    2571         527 :         FeedbackSlot slot = feedback_spec()->AddLoadICSlot();
    2572         527 :         builder()->LoadNamedProperty(object, name, feedback_index(slot));
    2573             :         break;
    2574             :       }
    2575             :       case KEYED_PROPERTY: {
    2576             :         // Key is already in accumulator at this point due to evaluating the
    2577             :         // LHS above.
    2578         830 :         FeedbackSlot slot = feedback_spec()->AddKeyedLoadICSlot();
    2579         830 :         builder()->LoadKeyedProperty(object, feedback_index(slot));
    2580             :         break;
    2581             :       }
    2582             :       case NAMED_SUPER_PROPERTY: {
    2583             :         builder()->CallRuntime(Runtime::kLoadFromSuper,
    2584          20 :                                super_property_args.Truncate(3));
    2585          20 :         break;
    2586             :       }
    2587             :       case KEYED_SUPER_PROPERTY: {
    2588             :         builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
    2589          40 :                                super_property_args.Truncate(3));
    2590          40 :         break;
    2591             :       }
    2592             :     }
    2593      302091 :     BinaryOperation* binop = expr->AsCompoundAssignment()->binary_operation();
    2594      100697 :     FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot();
    2595      100697 :     if (expr->value()->IsSmiLiteral()) {
    2596             :       builder()->BinaryOperationSmiLiteral(
    2597             :           binop->op(), expr->value()->AsLiteral()->AsSmiLiteral(),
    2598       51756 :           feedback_index(slot));
    2599             :     } else {
    2600       74819 :       Register old_value = register_allocator()->NewRegister();
    2601       74819 :       builder()->StoreAccumulatorInRegister(old_value);
    2602       74819 :       VisitForAccumulatorValue(expr->value());
    2603       74819 :       builder()->BinaryOperation(binop->op(), old_value, feedback_index(slot));
    2604             :     }
    2605             :   } else {
    2606     6527365 :     VisitForAccumulatorValue(expr->value());
    2607             :   }
    2608             : 
    2609             :   // Store the value.
    2610             :   builder()->SetExpressionPosition(expr);
    2611     6628061 :   switch (assign_type) {
    2612             :     case VARIABLE: {
    2613             :       // TODO(oth): The BuildVariableAssignment() call is hard to reason about.
    2614             :       // Is the value in the accumulator safe? Yes, but scary.
    2615    15115128 :       VariableProxy* proxy = expr->target()->AsVariableProxy();
    2616             :       BuildVariableAssignment(proxy->var(), expr->op(),
    2617             :                               proxy->hole_check_mode(),
    2618     5038376 :                               expr->lookup_hoisting_mode());
    2619     5038377 :       break;
    2620             :     }
    2621             :     case NAMED_PROPERTY: {
    2622     1529450 :       FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
    2623             :       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    2624     1529450 :                                     language_mode());
    2625             :       break;
    2626             :     }
    2627             :     case KEYED_PROPERTY: {
    2628       59687 :       FeedbackSlot slot = feedback_spec()->AddKeyedStoreICSlot(language_mode());
    2629             :       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    2630       59687 :                                     language_mode());
    2631             :       break;
    2632             :     }
    2633             :     case NAMED_SUPER_PROPERTY: {
    2634             :       builder()
    2635         217 :           ->StoreAccumulatorInRegister(super_property_args[3])
    2636         217 :           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
    2637         217 :       break;
    2638             :     }
    2639             :     case KEYED_SUPER_PROPERTY: {
    2640             :       builder()
    2641         331 :           ->StoreAccumulatorInRegister(super_property_args[3])
    2642         331 :           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
    2643         331 :       break;
    2644             :     }
    2645             :   }
    2646     6628062 : }
    2647             : 
    2648      100697 : void BytecodeGenerator::VisitCompoundAssignment(CompoundAssignment* expr) {
    2649      100697 :   VisitAssignment(expr);
    2650      100697 : }
    2651             : 
    2652             : // Suspends the generator to resume at |suspend_id|, with output stored in the
    2653             : // accumulator. When the generator is resumed, the sent value is loaded in the
    2654             : // accumulator.
    2655      160368 : void BytecodeGenerator::BuildSuspendPoint(int suspend_id) {
    2656       20046 :   RegisterList registers(0, register_allocator()->next_register_index());
    2657             : 
    2658             :   // Save context, registers, and state. Then return.
    2659       20046 :   builder()->SuspendGenerator(generator_object(), registers, suspend_id);
    2660             : 
    2661       40092 :   builder()->SetReturnPosition(kNoSourcePosition, info()->literal());
    2662       20046 :   builder()->Return();  // Hard return (ignore any finally blocks).
    2663             : 
    2664             :   // Upon resume, we continue here.
    2665       40092 :   builder()->Bind(generator_jump_table_, suspend_id);
    2666             : 
    2667             :   // Clobbers all registers.
    2668       20046 :   builder()->RestoreGeneratorRegisters(generator_object(), registers);
    2669             : 
    2670             :   // Update state to indicate that we have finished resuming. Loop headers
    2671             :   // rely on this.
    2672             :   builder()
    2673       20046 :       ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    2674       20046 :       .StoreAccumulatorInRegister(generator_state_);
    2675             : 
    2676             :   // When resuming execution of a generator, module or async function, the sent
    2677             :   // value is in the [[input_or_debug_pos]] slot.
    2678             :   builder()->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
    2679       20046 :                          generator_object());
    2680       20046 : }
    2681             : 
    2682      112161 : void BytecodeGenerator::VisitYield(Yield* expr) {
    2683             :   builder()->SetExpressionPosition(expr);
    2684       27018 :   VisitForAccumulatorValue(expr->expression());
    2685             : 
    2686        9006 :   if (!expr->IsInitialYield()) {
    2687        3729 :     if (IsAsyncGeneratorFunction(function_kind())) {
    2688             :       // AsyncGenerator yields (with the exception of the initial yield)
    2689             :       // delegate work to the AsyncGeneratorYield stub, which Awaits the operand
    2690             :       // and on success, wraps the value in an IteratorResult.
    2691             :       RegisterAllocationScope register_scope(this);
    2692         360 :       RegisterList args = register_allocator()->NewRegisterList(3);
    2693             :       builder()
    2694         360 :           ->MoveRegister(generator_object(), args[0])  // generator
    2695         360 :           .StoreAccumulatorInRegister(args[1])         // value
    2696         720 :           .LoadBoolean(catch_prediction() != HandlerTable::ASYNC_AWAIT)
    2697         360 :           .StoreAccumulatorInRegister(args[2])  // is_caught
    2698         360 :           .CallRuntime(Runtime::kInlineAsyncGeneratorYield, args);
    2699             :     } else {
    2700             :       // Generator yields (with the exception of the initial yield) wrap the
    2701             :       // value into IteratorResult.
    2702             :       RegisterAllocationScope register_scope(this);
    2703        3369 :       RegisterList args = register_allocator()->NewRegisterList(2);
    2704             :       builder()
    2705        3369 :           ->StoreAccumulatorInRegister(args[0])  // value
    2706        3369 :           .LoadFalse()
    2707        3369 :           .StoreAccumulatorInRegister(args[1])   // done
    2708        3369 :           .CallRuntime(Runtime::kInlineCreateIterResultObject, args);
    2709             :     }
    2710             :   }
    2711             : 
    2712        9006 :   BuildSuspendPoint(expr->suspend_id());
    2713             :   // At this point, the generator has been resumed, with the received value in
    2714             :   // the accumulator.
    2715             : 
    2716             :   // TODO(caitp): remove once yield* desugaring for async generators is handled
    2717             :   // in BytecodeGenerator.
    2718        9006 :   if (expr->on_abrupt_resume() == Yield::kNoControl) {
    2719             :     DCHECK(IsAsyncGeneratorFunction(function_kind()));
    2720           0 :     return;
    2721             :   }
    2722             : 
    2723        9006 :   Register input = register_allocator()->NewRegister();
    2724        9006 :   builder()->StoreAccumulatorInRegister(input).CallRuntime(
    2725        9006 :       Runtime::kInlineGeneratorGetResumeMode, generator_object());
    2726             : 
    2727             :   // Now dispatch on resume mode.
    2728             :   STATIC_ASSERT(JSGeneratorObject::kNext + 1 == JSGeneratorObject::kReturn);
    2729             :   BytecodeJumpTable* jump_table =
    2730        9006 :       builder()->AllocateJumpTable(2, JSGeneratorObject::kNext);
    2731             : 
    2732        9006 :   builder()->SwitchOnSmiNoFeedback(jump_table);
    2733             : 
    2734             :   {
    2735             :     // Resume with throw (switch fallthrough).
    2736             :     // TODO(leszeks): Add a debug-only check that the accumulator is
    2737             :     // JSGeneratorObject::kThrow.
    2738             :     builder()->SetExpressionPosition(expr);
    2739        9006 :     builder()->LoadAccumulatorWithRegister(input);
    2740        9006 :     builder()->Throw();
    2741             :   }
    2742             : 
    2743             :   {
    2744             :     // Resume with return.
    2745        9006 :     builder()->Bind(jump_table, JSGeneratorObject::kReturn);
    2746        9006 :     builder()->LoadAccumulatorWithRegister(input);
    2747        9006 :     if (IsAsyncGeneratorFunction(function_kind())) {
    2748             :       execution_control()->AsyncReturnAccumulator();
    2749             :     } else {
    2750             :       execution_control()->ReturnAccumulator();
    2751             :     }
    2752             :   }
    2753             : 
    2754             :   {
    2755             :     // Resume with next.
    2756        9006 :     builder()->Bind(jump_table, JSGeneratorObject::kNext);
    2757             :     BuildIncrementBlockCoverageCounterIfEnabled(expr,
    2758             :                                                 SourceRangeKind::kContinuation);
    2759        9006 :     builder()->LoadAccumulatorWithRegister(input);
    2760             :   }
    2761             : }
    2762             : 
    2763             : // Desugaring of (yield* iterable)
    2764             : //
    2765             : //   do {
    2766             : //     const kNext = 0;
    2767             : //     const kReturn = 1;
    2768             : //     const kThrow = 2;
    2769             : //
    2770             : //     let output; // uninitialized
    2771             : //
    2772             : //     let iterator = GetIterator(iterable);
    2773             : //     let input = undefined;
    2774             : //     let resumeMode = kNext;
    2775             : //
    2776             : //     while (true) {
    2777             : //       // From the generator to the iterator:
    2778             : //       // Forward input according to resumeMode and obtain output.
    2779             : //       switch (resumeMode) {
    2780             : //         case kNext:
    2781             : //           output = iterator.next(input);
    2782             : //           break;
    2783             : //         case kReturn:
    2784             : //           let iteratorReturn = iterator.return;
    2785             : //           if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
    2786             : //           output = %_Call(iteratorReturn, iterator, input);
    2787             : //           break;
    2788             : //         case kThrow:
    2789             : //           let iteratorThrow = iterator.throw;
    2790             : //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
    2791             : //             let iteratorReturn = iterator.return;
    2792             : //             if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
    2793             : //               output = %_Call(iteratorReturn, iterator);
    2794             : //               if (IS_ASYNC_GENERATOR) output = await output;
    2795             : //               if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    2796             : //             }
    2797             : //             throw MakeTypeError(kThrowMethodMissing);
    2798             : //           }
    2799             : //           output = %_Call(iteratorThrow, iterator, input);
    2800             : //           break;
    2801             : //       }
    2802             : //
    2803             : //       if (IS_ASYNC_GENERATOR) output = await output;
    2804             : //       if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
    2805             : //       if (output.done) break;
    2806             : //
    2807             : //       // From the generator to its user:
    2808             : //       // Forward output, receive new input, and determine resume mode.
    2809             : //       if (IS_ASYNC_GENERATOR) {
    2810             : //         // AsyncGeneratorYield abstract operation awaits the operand before
    2811             : //         // resolving the promise for the current AsyncGeneratorRequest.
    2812             : //         %_AsyncGeneratorYield(output.value)
    2813             : //       }
    2814             : //       input = Suspend(output);
    2815             : //       resumeMode = %GeneratorGetResumeMode();
    2816             : //     }
    2817             : //
    2818             : //     if (resumeMode === kReturn) {
    2819             : //       return output.value;
    2820             : //     }
    2821             : //     output.value
    2822             : //   }
    2823       10758 : void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
    2824         243 :   Register output = register_allocator()->NewRegister();
    2825         243 :   Register resume_mode = register_allocator()->NewRegister();
    2826             :   IteratorType iterator_type = IsAsyncGeneratorFunction(function_kind())
    2827             :                                    ? IteratorType::kAsync
    2828         243 :                                    : IteratorType::kNormal;
    2829             : 
    2830             :   {
    2831             :     RegisterAllocationScope register_scope(this);
    2832             : 
    2833         243 :     RegisterList iterator_and_input = register_allocator()->NewRegisterList(2);
    2834             : 
    2835             :     Register iterator = iterator_and_input[0];
    2836             : 
    2837         729 :     BuildGetIterator(expr->expression(), iterator_type);
    2838         243 :     builder()->StoreAccumulatorInRegister(iterator);
    2839         243 :     Register input = iterator_and_input[1];
    2840         243 :     builder()->LoadUndefined().StoreAccumulatorInRegister(input);
    2841             :     builder()
    2842         243 :         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
    2843         243 :         .StoreAccumulatorInRegister(resume_mode);
    2844             : 
    2845             :     {
    2846             :       // This loop builder does not construct counters as the loop is not
    2847             :       // visible to the user, and we therefore neither pass the block coverage
    2848             :       // builder nor the expression.
    2849             :       //
    2850             :       // YieldStar in AsyncGenerator functions includes 3 suspend points, rather
    2851             :       // than 1. These are documented in the YieldStar AST node.
    2852         243 :       LoopBuilder loop(builder(), nullptr, nullptr);
    2853         243 :       VisitIterationHeader(expr->suspend_id(), expr->suspend_count(), &loop);
    2854             : 
    2855             :       {
    2856             :         BytecodeLabels after_switch(zone());
    2857             :         BytecodeJumpTable* switch_jump_table =
    2858         243 :             builder()->AllocateJumpTable(2, 1);
    2859             : 
    2860             :         builder()
    2861         243 :             ->LoadAccumulatorWithRegister(resume_mode)
    2862         243 :             .SwitchOnSmiNoFeedback(switch_jump_table);
    2863             : 
    2864             :         // Fallthrough to default case.
    2865             :         // TODO(tebbi): Add debug code to check that {resume_mode} really is
    2866             :         // {JSGeneratorObject::kNext} in this case.
    2867             :         STATIC_ASSERT(JSGeneratorObject::kNext == 0);
    2868             :         {
    2869             :           RegisterAllocationScope register_scope(this);
    2870             :           // output = iterator.next(input);
    2871         243 :           Register iterator_next = register_allocator()->NewRegister();
    2872         243 :           FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
    2873         243 :           FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
    2874             :           builder()
    2875             :               ->LoadNamedProperty(iterator,
    2876             :                                   ast_string_constants()->next_string(),
    2877         486 :                                   feedback_index(load_slot))
    2878         243 :               .StoreAccumulatorInRegister(iterator_next)
    2879             :               .CallProperty(iterator_next, iterator_and_input,
    2880         243 :                             feedback_index(call_slot))
    2881         486 :               .Jump(after_switch.New());
    2882             :         }
    2883             : 
    2884             :         STATIC_ASSERT(JSGeneratorObject::kReturn == 1);
    2885         243 :         builder()->Bind(switch_jump_table, JSGeneratorObject::kReturn);
    2886             :         {
    2887             :           RegisterAllocationScope register_scope(this);
    2888             :           BytecodeLabels return_input(zone());
    2889             :           // Trigger return from within the inner iterator.
    2890         243 :           Register iterator_return = register_allocator()->NewRegister();
    2891         243 :           FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
    2892         243 :           FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
    2893             :           builder()
    2894             :               ->LoadNamedProperty(iterator,
    2895             :                                   ast_string_constants()->return_string(),
    2896         486 :                                   feedback_index(load_slot))
    2897         486 :               .JumpIfUndefined(return_input.New())
    2898         486 :               .JumpIfNull(return_input.New())
    2899         243 :               .StoreAccumulatorInRegister(iterator_return)
    2900             :               .CallProperty(iterator_return, iterator_and_input,
    2901         243 :                             feedback_index(call_slot))
    2902         486 :               .Jump(after_switch.New());
    2903             : 
    2904         243 :           return_input.Bind(builder());
    2905             :           {
    2906         243 :             builder()->LoadAccumulatorWithRegister(input);
    2907         243 :             if (iterator_type == IteratorType::kAsync) {
    2908             :               execution_control()->AsyncReturnAccumulator();
    2909             :             } else {
    2910             :               execution_control()->ReturnAccumulator();
    2911             :             }
    2912         243 :           }
    2913             :         }
    2914             : 
    2915             :         STATIC_ASSERT(JSGeneratorObject::kThrow == 2);
    2916         243 :         builder()->Bind(switch_jump_table, JSGeneratorObject::kThrow);
    2917             :         {
    2918             :           BytecodeLabels iterator_throw_is_undefined(zone());
    2919             :           {
    2920             :             RegisterAllocationScope register_scope(this);
    2921             :             // If the inner iterator has a throw method, use it to trigger an
    2922             :             // exception inside.
    2923         243 :             Register iterator_throw = register_allocator()->NewRegister();
    2924         243 :             FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
    2925         243 :             FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
    2926             :             builder()
    2927             :                 ->LoadNamedProperty(iterator,
    2928             :                                     ast_string_constants()->throw_string(),
    2929         486 :                                     feedback_index(load_slot))
    2930         486 :                 .JumpIfUndefined(iterator_throw_is_undefined.New())
    2931         486 :                 .JumpIfNull(iterator_throw_is_undefined.New())
    2932         243 :                 .StoreAccumulatorInRegister(iterator_throw);
    2933             :             builder()
    2934             :                 ->CallProperty(iterator_throw, iterator_and_input,
    2935         243 :                                feedback_index(call_slot))
    2936         486 :                 .Jump(after_switch.New());
    2937             :           }
    2938             : 
    2939         243 :           iterator_throw_is_undefined.Bind(builder());
    2940             :           {
    2941             :             RegisterAllocationScope register_scope(this);
    2942             :             BytecodeLabels throw_throw_method_missing(zone());
    2943         243 :             Register iterator_return = register_allocator()->NewRegister();
    2944             :             // If iterator.throw does not exist, try to use iterator.return to
    2945             :             // inform the iterator that it should stop.
    2946         243 :             FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
    2947         243 :             FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
    2948             :             builder()
    2949             :                 ->LoadNamedProperty(iterator,
    2950             :                                     ast_string_constants()->return_string(),
    2951         486 :                                     feedback_index(load_slot))
    2952         243 :                 .StoreAccumulatorInRegister(iterator_return);
    2953             :             builder()
    2954         486 :                 ->JumpIfUndefined(throw_throw_method_missing.New())
    2955         486 :                 .JumpIfNull(throw_throw_method_missing.New())
    2956             :                 .CallProperty(iterator_return, RegisterList(iterator),
    2957         243 :                               feedback_index(call_slot));
    2958             : 
    2959         243 :             if (iterator_type == IteratorType::kAsync) {
    2960             :               // For async generators, await the result of the .return() call.
    2961          11 :               BuildAwait(expr->await_iterator_close_suspend_id());
    2962          11 :               builder()->StoreAccumulatorInRegister(output);
    2963             :             }
    2964             : 
    2965             :             builder()
    2966         486 :                 ->JumpIfJSReceiver(throw_throw_method_missing.New())
    2967         243 :                 .CallRuntime(Runtime::kThrowIteratorResultNotAnObject, output);
    2968             : 
    2969         243 :             throw_throw_method_missing.Bind(builder());
    2970         486 :             builder()->CallRuntime(Runtime::kThrowThrowMethodMissing);
    2971             :           }
    2972             :         }
    2973             : 
    2974         243 :         after_switch.Bind(builder());
    2975             :       }
    2976             : 
    2977         243 :       if (iterator_type == IteratorType::kAsync) {
    2978             :         // Await the result of the method invocation.
    2979          11 :         BuildAwait(expr->await_delegated_iterator_output_suspend_id());
    2980             :       }
    2981             : 
    2982             :       // Check that output is an object.
    2983             :       BytecodeLabel check_if_done;
    2984             :       builder()
    2985         243 :           ->StoreAccumulatorInRegister(output)
    2986         243 :           .JumpIfJSReceiver(&check_if_done)
    2987         243 :           .CallRuntime(Runtime::kThrowIteratorResultNotAnObject, output);
    2988             : 
    2989         243 :       builder()->Bind(&check_if_done);
    2990             :       // Break once output.done is true.
    2991             :       builder()->LoadNamedProperty(
    2992             :           output, ast_string_constants()->done_string(),
    2993         729 :           feedback_index(feedback_spec()->AddLoadICSlot()));
    2994             : 
    2995             :       loop.BreakIfTrue(ToBooleanMode::kConvertToBoolean);
    2996             : 
    2997             :       // Suspend the current generator.
    2998         243 :       if (iterator_type == IteratorType::kNormal) {
    2999         232 :         builder()->LoadAccumulatorWithRegister(output);
    3000             :       } else {
    3001             :         RegisterAllocationScope register_scope(this);
    3002             :         DCHECK_EQ(iterator_type, IteratorType::kAsync);
    3003             :         // If generatorKind is async, perform AsyncGeneratorYield(output.value),
    3004             :         // which will await `output.value` before resolving the current
    3005             :         // AsyncGeneratorRequest's promise.
    3006             :         builder()->LoadNamedProperty(
    3007             :             output, ast_string_constants()->value_string(),
    3008          33 :             feedback_index(feedback_spec()->AddLoadICSlot()));
    3009             : 
    3010          11 :         RegisterList args = register_allocator()->NewRegisterList(3);
    3011             :         builder()
    3012          11 :             ->MoveRegister(generator_object(), args[0])  // generator
    3013          11 :             .StoreAccumulatorInRegister(args[1])         // value
    3014          22 :             .LoadBoolean(catch_prediction() != HandlerTable::ASYNC_AWAIT)
    3015          11 :             .StoreAccumulatorInRegister(args[2])  // is_caught
    3016          11 :             .CallRuntime(Runtime::kInlineAsyncGeneratorYield, args);
    3017             :       }
    3018             : 
    3019         243 :       BuildSuspendPoint(expr->suspend_id());
    3020         243 :       builder()->StoreAccumulatorInRegister(input);
    3021             :       builder()
    3022             :           ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode,
    3023         243 :                         generator_object())
    3024         243 :           .StoreAccumulatorInRegister(resume_mode);
    3025             : 
    3026         243 :       loop.BindContinueTarget();
    3027         243 :       loop.JumpToHeader(loop_depth_);
    3028         243 :     }
    3029             :   }
    3030             : 
    3031             :   // Decide if we trigger a return or if the yield* expression should just
    3032             :   // produce a value.
    3033             :   BytecodeLabel completion_is_output_value;
    3034         243 :   Register output_value = register_allocator()->NewRegister();
    3035             :   builder()
    3036             :       ->LoadNamedProperty(output, ast_string_constants()->value_string(),
    3037         729 :                           feedback_index(feedback_spec()->AddLoadICSlot()))
    3038         243 :       .StoreAccumulatorInRegister(output_value)
    3039         243 :       .LoadLiteral(Smi::FromInt(JSGeneratorObject::kReturn))
    3040         243 :       .CompareOperation(Token::EQ_STRICT, resume_mode)
    3041         243 :       .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &completion_is_output_value)
    3042         243 :       .LoadAccumulatorWithRegister(output_value);
    3043         243 :   if (iterator_type == IteratorType::kAsync) {
    3044             :     execution_control()->AsyncReturnAccumulator();
    3045             :   } else {
    3046             :     execution_control()->ReturnAccumulator();
    3047             :   }
    3048             : 
    3049         243 :   builder()->Bind(&completion_is_output_value);
    3050             :   BuildIncrementBlockCoverageCounterIfEnabled(expr,
    3051             :                                               SourceRangeKind::kContinuation);
    3052         243 :   builder()->LoadAccumulatorWithRegister(output_value);
    3053         243 : }
    3054             : 
    3055      105508 : void BytecodeGenerator::BuildAwait(int suspend_id) {
    3056             :   // Rather than HandlerTable::UNCAUGHT, async functions use
    3057             :   // HandlerTable::ASYNC_AWAIT to communicate that top-level exceptions are
    3058             :   // transformed into promise rejections. This is necessary to prevent emitting
    3059             :   // multiple debug events for the same uncaught exception. There is no point
    3060             :   // in the body of an async function where catch prediction is
    3061             :   // HandlerTable::UNCAUGHT.
    3062             :   DCHECK(catch_prediction() != HandlerTable::UNCAUGHT);
    3063             : 
    3064             :   {
    3065             :     // Await(operand) and suspend.
    3066             :     RegisterAllocationScope register_scope(this);
    3067             : 
    3068             :     int await_builtin_context_index;
    3069             :     RegisterList args;
    3070       10797 :     if (IsAsyncGeneratorFunction(function_kind())) {
    3071             :       await_builtin_context_index =
    3072             :           catch_prediction() == HandlerTable::ASYNC_AWAIT
    3073             :               ? Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT
    3074        1231 :               : Context::ASYNC_GENERATOR_AWAIT_CAUGHT;
    3075        1231 :       args = register_allocator()->NewRegisterList(2);
    3076             :       builder()
    3077        1231 :           ->MoveRegister(generator_object(), args[0])
    3078        1231 :           .StoreAccumulatorInRegister(args[1]);
    3079             :     } else {
    3080             :       await_builtin_context_index =
    3081             :           catch_prediction() == HandlerTable::ASYNC_AWAIT
    3082             :               ? Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX
    3083        9566 :               : Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX;
    3084        9566 :       args = register_allocator()->NewRegisterList(3);
    3085             :       builder()
    3086        9566 :           ->MoveRegister(generator_object(), args[0])
    3087        9566 :           .StoreAccumulatorInRegister(args[1]);
    3088             : 
    3089             :       // AsyncFunction Await builtins require a 3rd parameter to hold the outer
    3090             :       // promise.
    3091             :       Variable* var_promise = closure_scope()->promise_var();
    3092        9566 :       BuildVariableLoadForAccumulatorValue(var_promise, HoleCheckMode::kElided);
    3093        9566 :       builder()->StoreAccumulatorInRegister(args[2]);
    3094             :     }
    3095             : 
    3096       10797 :     builder()->CallJSRuntime(await_builtin_context_index, args);
    3097             :   }
    3098             : 
    3099       10797 :   BuildSuspendPoint(suspend_id);
    3100             : 
    3101       10797 :   Register input = register_allocator()->NewRegister();
    3102       10797 :   Register resume_mode = register_allocator()->NewRegister();
    3103             : 
    3104             :   // Now dispatch on resume mode.
    3105             :   BytecodeLabel resume_next;
    3106             :   builder()
    3107       10797 :       ->StoreAccumulatorInRegister(input)
    3108       10797 :       .CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator_object())
    3109       10797 :       .StoreAccumulatorInRegister(resume_mode)
    3110       10797 :       .LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
    3111       10797 :       .CompareOperation(Token::EQ_STRICT, resume_mode)
    3112       10797 :       .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_next);
    3113             : 
    3114             :   // Resume with "throw" completion (rethrow the received value).
    3115             :   // TODO(leszeks): Add a debug-only check that the accumulator is
    3116             :   // JSGeneratorObject::kThrow.
    3117       10797 :   builder()->LoadAccumulatorWithRegister(input).ReThrow();
    3118             : 
    3119             :   // Resume with next.
    3120       10797 :   builder()->Bind(&resume_next);
    3121       10797 :   builder()->LoadAccumulatorWithRegister(input);
    3122       10797 : }
    3123             : 
    3124       10775 : void BytecodeGenerator::VisitAwait(Await* expr) {
    3125             :   builder()->SetExpressionPosition(expr);
    3126       10775 :   VisitForAccumulatorValue(expr->expression());
    3127       10775 :   BuildAwait(expr->suspend_id());
    3128             :   BuildIncrementBlockCoverageCounterIfEnabled(expr,
    3129             :                                               SourceRangeKind::kContinuation);
    3130       10775 : }
    3131             : 
    3132      281976 : void BytecodeGenerator::VisitThrow(Throw* expr) {
    3133             :   AllocateBlockCoverageSlotIfEnabled(expr, SourceRangeKind::kContinuation);
    3134       70494 :   VisitForAccumulatorValue(expr->exception());
    3135             :   builder()->SetExpressionPosition(expr);
    3136       70494 :   builder()->Throw();
    3137       70494 : }
    3138             : 
    3139    14894717 : void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) {
    3140     3724230 :   LhsKind property_kind = Property::GetAssignType(property);
    3141     3724231 :   switch (property_kind) {
    3142             :     case VARIABLE:
    3143           0 :       UNREACHABLE();
    3144             :     case NAMED_PROPERTY: {
    3145             :       builder()->SetExpressionPosition(property);
    3146             :       builder()->LoadNamedProperty(
    3147             :           obj, property->key()->AsLiteral()->AsRawPropertyName(),
    3148    14030699 :           feedback_index(feedback_spec()->AddLoadICSlot()));
    3149     3507675 :       break;
    3150             :     }
    3151             :     case KEYED_PROPERTY: {
    3152      215821 :       VisitForAccumulatorValue(property->key());
    3153             :       builder()->SetExpressionPosition(property);
    3154             :       builder()->LoadKeyedProperty(
    3155      431642 :           obj, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
    3156      215821 :       break;
    3157             :     }
    3158             :     case NAMED_SUPER_PROPERTY:
    3159         386 :       VisitNamedSuperPropertyLoad(property, Register::invalid_value());
    3160         386 :       break;
    3161             :     case KEYED_SUPER_PROPERTY:
    3162         350 :       VisitKeyedSuperPropertyLoad(property, Register::invalid_value());
    3163         350 :       break;
    3164             :   }
    3165     3724232 : }
    3166             : 
    3167      835465 : void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj,
    3168             :                                                      Property* expr,
    3169      835465 :                                                      Register destination) {
    3170             :   ValueResultScope result_scope(this);
    3171      835465 :   VisitPropertyLoad(obj, expr);
    3172      835465 :   builder()->StoreAccumulatorInRegister(destination);
    3173      835465 : }
    3174             : 
    3175        2286 : void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
    3176        1900 :                                                     Register opt_receiver_out) {
    3177             :   RegisterAllocationScope register_scope(this);
    3178        1524 :   SuperPropertyReference* super_property =
    3179         762 :       property->obj()->AsSuperPropertyReference();
    3180         762 :   RegisterList args = register_allocator()->NewRegisterList(3);
    3181             :   VisitForRegisterValue(super_property->this_var(), args[0]);
    3182             :   VisitForRegisterValue(super_property->home_object(), args[1]);
    3183             : 
    3184             :   builder()->SetExpressionPosition(property);
    3185             :   builder()
    3186        2286 :       ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    3187         762 :       .StoreAccumulatorInRegister(args[2])
    3188         762 :       .CallRuntime(Runtime::kLoadFromSuper, args);
    3189             : 
    3190         762 :   if (opt_receiver_out.is_valid()) {
    3191         376 :     builder()->MoveRegister(args[0], opt_receiver_out);
    3192         762 :   }
    3193         762 : }
    3194             : 
    3195        1146 : void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
    3196         796 :                                                     Register opt_receiver_out) {
    3197             :   RegisterAllocationScope register_scope(this);
    3198         764 :   SuperPropertyReference* super_property =
    3199         382 :       property->obj()->AsSuperPropertyReference();
    3200         382 :   RegisterList args = register_allocator()->NewRegisterList(3);
    3201             :   VisitForRegisterValue(super_property->this_var(), args[0]);
    3202             :   VisitForRegisterValue(super_property->home_object(), args[1]);
    3203             :   VisitForRegisterValue(property->key(), args[2]);
    3204             : 
    3205             :   builder()->SetExpressionPosition(property);
    3206         382 :   builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, args);
    3207             : 
    3208         382 :   if (opt_receiver_out.is_valid()) {
    3209          32 :     builder()->MoveRegister(args[0], opt_receiver_out);
    3210         382 :   }
    3211         382 : }
    3212             : 
    3213     5776798 : void BytecodeGenerator::VisitProperty(Property* expr) {
    3214     2888767 :   LhsKind property_kind = Property::GetAssignType(expr);
    3215     2888767 :   if (property_kind != NAMED_SUPER_PROPERTY &&
    3216             :       property_kind != KEYED_SUPER_PROPERTY) {
    3217     2888031 :     Register obj = VisitForRegisterValue(expr->obj());
    3218     2888031 :     VisitPropertyLoad(obj, expr);
    3219             :   } else {
    3220         736 :     VisitPropertyLoad(Register::invalid_value(), expr);
    3221             :   }
    3222     2888766 : }
    3223             : 
    3224    13955615 : void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args,
    3225             :                                        RegisterList* arg_regs) {
    3226             :   // Visit arguments.
    3227    21296998 :   for (int i = 0; i < static_cast<int>(args->length()); i++) {
    3228     7341382 :     VisitAndPushIntoRegisterList(args->at(i), arg_regs);
    3229             :   }
    3230     3307117 : }
    3231             : 
    3232    20046961 : void BytecodeGenerator::VisitCall(Call* expr) {
    3233             :   Expression* callee_expr = expr->expression();
    3234     2665847 :   Call::CallType call_type = expr->GetCallType();
    3235             : 
    3236     2665849 :   if (call_type == Call::SUPER_CALL) {
    3237     2669611 :     return VisitCallSuper(expr);
    3238             :   }
    3239             : 
    3240             :   // Grow the args list as we visit receiver / arguments to avoid allocating all
    3241             :   // the registers up-front. Otherwise these registers are unavailable during
    3242             :   // receiver / argument visiting and we can end up with memory leaks due to
    3243             :   // registers keeping objects alive.
    3244     2662087 :   Register callee = register_allocator()->NewRegister();
    3245     2662086 :   RegisterList args = register_allocator()->NewGrowableRegisterList();
    3246             : 
    3247             :   bool implicit_undefined_receiver = false;
    3248             :   // When a call contains a spread, a Call AST node is only created if there is
    3249             :   // exactly one spread, and it is the last argument.
    3250     2662086 :   bool is_spread_call = expr->only_last_arg_is_spread();
    3251             : 
    3252             :   // TODO(petermarshall): We have a lot of call bytecodes that are very similar,
    3253             :   // see if we can reduce the number by adding a separate argument which
    3254             :   // specifies the call type (e.g., property, spread, tailcall, etc.).
    3255             : 
    3256             :   // Prepare the callee and the receiver to the function call. This depends on
    3257             :   // the semantics of the underlying call type.
    3258     2662086 :   switch (call_type) {
    3259             :     case Call::NAMED_PROPERTY_CALL:
    3260             :     case Call::KEYED_PROPERTY_CALL: {
    3261     1670930 :       Property* property = callee_expr->AsProperty();
    3262      835465 :       VisitAndPushIntoRegisterList(property->obj(), &args);
    3263      835465 :       VisitPropertyLoadForRegister(args.last_register(), property, callee);
    3264      835465 :       break;
    3265             :     }
    3266             :     case Call::GLOBAL_CALL: {
    3267             :       // Receiver is undefined for global calls.
    3268     1087090 :       if (!is_spread_call) {
    3269             :         implicit_undefined_receiver = true;
    3270             :       } else {
    3271             :         // TODO(leszeks): There's no special bytecode for tail calls or spread
    3272             :         // calls with an undefined receiver, so just push undefined ourselves.
    3273          17 :         BuildPushUndefinedIntoRegisterList(&args);
    3274             :       }
    3275             :       // Load callee as a global variable.
    3276     3261270 :       VariableProxy* proxy = callee_expr->AsVariableProxy();
    3277             :       BuildVariableLoadForAccumulatorValue(proxy->var(),
    3278     1087090 :                                            proxy->hole_check_mode());
    3279     1087090 :       builder()->StoreAccumulatorInRegister(callee);
    3280     1087090 :       break;
    3281             :     }
    3282             :     case Call::WITH_CALL: {
    3283        2141 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    3284             :       DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot());
    3285             :       {
    3286             :         RegisterAllocationScope inner_register_scope(this);
    3287        2141 :         Register name = register_allocator()->NewRegister();
    3288             : 
    3289             :         // Call %LoadLookupSlotForCall to get the callee and receiver.
    3290             :         DCHECK(Register::AreContiguous(callee, receiver));
    3291             :         RegisterList result_pair(callee.index(), 2);
    3292             :         USE(receiver);
    3293             : 
    3294        4282 :         Variable* variable = callee_expr->AsVariableProxy()->var();
    3295             :         builder()
    3296        2141 :             ->LoadLiteral(variable->raw_name())
    3297        2141 :             .StoreAccumulatorInRegister(name)
    3298             :             .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name,
    3299        2141 :                                 result_pair);
    3300             :       }
    3301             :       break;
    3302             :     }
    3303             :     case Call::OTHER_CALL: {
    3304             :       // Receiver is undefined for other calls.
    3305      736981 :       if (!is_spread_call) {
    3306             :         implicit_undefined_receiver = true;
    3307             :       } else {
    3308             :         // TODO(leszeks): There's no special bytecode for tail calls or spread
    3309             :         // calls with an undefined receiver, so just push undefined ourselves.
    3310         579 :         BuildPushUndefinedIntoRegisterList(&args);
    3311             :       }
    3312             :       VisitForRegisterValue(callee_expr, callee);
    3313             :       break;
    3314             :     }
    3315             :     case Call::NAMED_SUPER_PROPERTY_CALL: {
    3316         376 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    3317         376 :       Property* property = callee_expr->AsProperty();
    3318         376 :       VisitNamedSuperPropertyLoad(property, receiver);
    3319         376 :       builder()->StoreAccumulatorInRegister(callee);
    3320             :       break;
    3321             :     }
    3322             :     case Call::KEYED_SUPER_PROPERTY_CALL: {
    3323          32 :       Register receiver = register_allocator()->GrowRegisterList(&args);
    3324          32 :       Property* property = callee_expr->AsProperty();
    3325          32 :       VisitKeyedSuperPropertyLoad(property, receiver);
    3326          32 :       builder()->StoreAccumulatorInRegister(callee);
    3327             :       break;
    3328             :     }
    3329             :     case Call::SUPER_CALL:
    3330           0 :       UNREACHABLE();
    3331             :       break;
    3332             :   }
    3333             : 
    3334             :   // Evaluate all arguments to the function call and store in sequential args
    3335             :   // registers.
    3336     2662088 :   VisitArguments(expr->arguments(), &args);
    3337     2662083 :   int reciever_arg_count = implicit_undefined_receiver ? 0 : 1;
    3338     5324166 :   CHECK_EQ(reciever_arg_count + expr->arguments()->length(),
    3339             :            args.register_count());
    3340             : 
    3341             :   // Resolve callee for a potential direct eval call. This block will mutate the
    3342             :   // callee value.
    3343     2662083 :   if (expr->is_possibly_eval() && expr->arguments()->length() > 0) {
    3344             :     RegisterAllocationScope inner_register_scope(this);
    3345             :     // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
    3346             :     // strings and function closure, and loading language and
    3347             :     // position.
    3348      212644 :     Register first_arg = args[reciever_arg_count];
    3349      106322 :     RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
    3350             :     builder()
    3351      106322 :         ->MoveRegister(callee, runtime_call_args[0])
    3352      106322 :         .MoveRegister(first_arg, runtime_call_args[1])
    3353      212644 :         .MoveRegister(Register::function_closure(), runtime_call_args[2])
    3354      106322 :         .LoadLiteral(Smi::FromEnum(language_mode()))
    3355      106322 :         .StoreAccumulatorInRegister(runtime_call_args[3])
    3356      212644 :         .LoadLiteral(Smi::FromInt(current_scope()->start_position()))
    3357      106322 :         .StoreAccumulatorInRegister(runtime_call_args[4])
    3358      212644 :         .LoadLiteral(Smi::FromInt(expr->position()))
    3359      106322 :         .StoreAccumulatorInRegister(runtime_call_args[5]);
    3360             : 
    3361             :     // Call ResolvePossiblyDirectEval and modify the callee.
    3362             :     builder()
    3363      106322 :         ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
    3364      106322 :         .StoreAccumulatorInRegister(callee);
    3365             :   }
    3366             : 
    3367             :   builder()->SetExpressionPosition(expr);
    3368             : 
    3369     2662083 :   int feedback_slot_index = feedback_index(feedback_spec()->AddCallICSlot());
    3370             : 
    3371     2662086 :   if (is_spread_call) {
    3372             :     DCHECK(!implicit_undefined_receiver);
    3373        1491 :     builder()->CallWithSpread(callee, args, feedback_slot_index);
    3374     2660595 :   } else if (call_type == Call::NAMED_PROPERTY_CALL ||
    3375             :              call_type == Call::KEYED_PROPERTY_CALL) {
    3376             :     DCHECK(!implicit_undefined_receiver);
    3377      834595 :     builder()->CallProperty(callee, args, feedback_slot_index);
    3378     1826000 :   } else if (implicit_undefined_receiver) {
    3379     1823476 :     builder()->CallUndefinedReceiver(callee, args, feedback_slot_index);
    3380             :   } else {
    3381        2524 :     builder()->CallAnyReceiver(callee, args, feedback_slot_index);
    3382             :   }
    3383             : }
    3384             : 
    3385       26334 : void BytecodeGenerator::VisitCallSuper(Call* expr) {
    3386             :   RegisterAllocationScope register_scope(this);
    3387       11286 :   SuperCallReference* super = expr->expression()->AsSuperCallReference();
    3388             : 
    3389             :   // Prepare the constructor to the super call.
    3390        3762 :   VisitForAccumulatorValue(super->this_function_var());
    3391        3762 :   Register constructor = register_allocator()->NewRegister();
    3392        3762 :   builder()->GetSuperConstructor(constructor);
    3393             : 
    3394             :   ZoneList<Expression*>* args = expr->arguments();
    3395        3762 :   RegisterList args_regs = register_allocator()->NewGrowableRegisterList();
    3396        3762 :   VisitArguments(args, &args_regs);
    3397             :   // The new target is loaded into the accumulator from the
    3398             :   // {new.target} variable.
    3399        3762 :   VisitForAccumulatorValue(super->new_target_var());
    3400             :   builder()->SetExpressionPosition(expr);
    3401             : 
    3402        3762 :   int feedback_slot_index = feedback_index(feedback_spec()->AddCallICSlot());
    3403             : 
    3404             :   // When a super call contains a spread, a CallSuper AST node is only created
    3405             :   // if there is exactly one spread, and it is the last argument.
    3406        3762 :   if (expr->only_last_arg_is_spread()) {
    3407        2849 :     builder()->ConstructWithSpread(constructor, args_regs, feedback_slot_index);
    3408             :   } else {
    3409             :     // Call construct.
    3410             :     // TODO(turbofan): For now we do gather feedback on super constructor
    3411             :     // calls, utilizing the existing machinery to inline the actual call
    3412             :     // target and the JSCreate for the implicit receiver allocation. This
    3413             :     // is not an ideal solution for super constructor calls, but it gets
    3414             :     // the job done for now. In the long run we might want to revisit this
    3415             :     // and come up with a better way.
    3416         913 :     builder()->Construct(constructor, args_regs, feedback_slot_index);
    3417        3762 :   }
    3418        3762 : }
    3419             : 
    3420      937416 : void BytecodeGenerator::VisitCallNew(CallNew* expr) {
    3421      156236 :   Register constructor = VisitForRegisterValue(expr->expression());
    3422      156236 :   RegisterList args = register_allocator()->NewGrowableRegisterList();
    3423      156236 :   VisitArguments(expr->arguments(), &args);
    3424             : 
    3425             :   // The accumulator holds new target which is the same as the
    3426             :   // constructor for CallNew.
    3427             :   builder()->SetExpressionPosition(expr);
    3428      156236 :   builder()->LoadAccumulatorWithRegister(constructor);
    3429             : 
    3430      156236 :   int feedback_slot_index = feedback_index(feedback_spec()->AddCallICSlot());
    3431      156236 :   if (expr->only_last_arg_is_spread()) {
    3432         122 :     builder()->ConstructWithSpread(constructor, args, feedback_slot_index);
    3433             :   } else {
    3434      156114 :     builder()->Construct(constructor, args, feedback_slot_index);
    3435             :   }
    3436      156236 : }
    3437             : 
    3438     1862200 : void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    3439      485034 :   if (expr->is_jsruntime()) {
    3440       77936 :     RegisterList args = register_allocator()->NewGrowableRegisterList();
    3441       77936 :     VisitArguments(expr->arguments(), &args);
    3442       77936 :     builder()->CallJSRuntime(expr->context_index(), args);
    3443             :   } else {
    3444             :     // Evaluate all arguments to the runtime call.
    3445      407098 :     RegisterList args = register_allocator()->NewGrowableRegisterList();
    3446      407098 :     VisitArguments(expr->arguments(), &args);
    3447      407098 :     Runtime::FunctionId function_id = expr->function()->function_id;
    3448      407098 :     builder()->CallRuntime(function_id, args);
    3449             :   }
    3450      485034 : }
    3451             : 
    3452       21964 : void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
    3453       10982 :   VisitForEffect(expr->expression());
    3454       10982 :   builder()->LoadUndefined();
    3455           0 : }
    3456             : 
    3457      203426 : void BytecodeGenerator::VisitForTypeOfValue(Expression* expr) {
    3458      203426 :   if (expr->IsVariableProxy()) {
    3459             :     // Typeof does not throw a reference error on global variables, hence we
    3460             :     // perform a non-contextual load in case the operand is a variable proxy.
    3461      569292 :     VariableProxy* proxy = expr->AsVariableProxy();
    3462             :     BuildVariableLoadForAccumulatorValue(proxy->var(), proxy->hole_check_mode(),
    3463      189764 :                                          INSIDE_TYPEOF);
    3464             :   } else {
    3465       13662 :     VisitForAccumulatorValue(expr);
    3466             :   }
    3467      203426 : }
    3468             : 
    3469      115648 : void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
    3470       57824 :   VisitForTypeOfValue(expr->expression());
    3471       57824 :   builder()->TypeOf();
    3472           0 : }
    3473             : 
    3474      811564 : void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
    3475      344653 :   if (execution_result()->IsEffect()) {
    3476         136 :     VisitForEffect(expr->expression());
    3477      344517 :   } else if (execution_result()->IsTest()) {
    3478             :     // No actual logical negation happening, we just swap the control flow, by
    3479             :     // swapping the target labels and the fallthrough branch, and visit in the
    3480             :     // same test result context.
    3481             :     TestResultScope* test_result = execution_result()->AsTest();
    3482             :     test_result->InvertControlFlow();
    3483      283388 :     VisitInSameTestExecutionScope(expr->expression());
    3484             :   } else {
    3485       61129 :     TypeHint type_hint = VisitForAccumulatorValue(expr->expression());
    3486       61129 :     builder()->LogicalNot(ToBooleanModeFromTypeHint(type_hint));
    3487             :     // Always returns a boolean value.
    3488             :     execution_result()->SetResultIsBoolean();
    3489             :   }
    3490      344653 : }
    3491             : 
    3492      671069 : void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
    3493      473709 :   switch (expr->op()) {
    3494             :     case Token::Value::NOT:
    3495      344653 :       VisitNot(expr);
    3496      344653 :       break;
    3497             :     case Token::Value::TYPEOF:
    3498             :       VisitTypeOf(expr);
    3499             :       break;
    3500             :     case Token::Value::VOID:
    3501             :       VisitVoid(expr);
    3502             :       break;
    3503             :     case Token::Value::DELETE:
    3504       10910 :       VisitDelete(expr);
    3505       10910 :       break;
    3506             :     case Token::Value::ADD:
    3507             :     case Token::Value::SUB:
    3508             :     case Token::Value::BIT_NOT:
    3509       49340 :       VisitForAccumulatorValue(expr->expression());
    3510             :       builder()->SetExpressionPosition(expr);
    3511             :       builder()->UnaryOperation(
    3512       98680 :           expr->op(), feedback_index(feedback_spec()->AddBinaryOpICSlot()));
    3513       49340 :       break;
    3514             :     default:
    3515           0 :       UNREACHABLE();
    3516             :   }
    3517      473709 : }
    3518             : 
    3519       34134 : void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
    3520       10910 :   if (expr->expression()->IsProperty()) {
    3521             :     // Delete of an object property is allowed both in sloppy
    3522             :     // and strict modes.
    3523       28518 :     Property* property = expr->expression()->AsProperty();
    3524        9506 :     Register object = VisitForRegisterValue(property->obj());
    3525        9506 :     VisitForAccumulatorValue(property->key());
    3526        9506 :     builder()->Delete(object, language_mode());
    3527        1404 :   } else if (expr->expression()->IsVariableProxy()) {
    3528             :     // Delete of an unqualified identifier is allowed in sloppy mode but is
    3529             :     // not allowed in strict mode. Deleting 'this' and 'new.target' is allowed
    3530             :     // in both modes.
    3531        2725 :     VariableProxy* proxy = expr->expression()->AsVariableProxy();
    3532             :     DCHECK(is_sloppy(language_mode()) || proxy->is_this() ||
    3533             :            proxy->is_new_target());
    3534        1798 :     if (proxy->is_this() || proxy->is_new_target()) {
    3535          86 :       builder()->LoadTrue();
    3536             :     } else {
    3537        1526 :       Variable* variable = proxy->var();
    3538         851 :       switch (variable->location()) {
    3539             :         case VariableLocation::PARAMETER:
    3540             :         case VariableLocation::LOCAL:
    3541             :         case VariableLocation::CONTEXT: {
    3542             :           // Deleting local var/let/const, context variables, and arguments
    3543             :           // does not have any effect.
    3544         176 :           builder()->LoadFalse();
    3545         176 :           break;
    3546             :         }
    3547             :         case VariableLocation::UNALLOCATED:
    3548             :         // TODO(adamk): Falling through to the runtime results in correct
    3549             :         // behavior, but does unnecessary context-walking (since scope
    3550             :         // analysis has already proven that the variable doesn't exist in
    3551             :         // any non-global scope). Consider adding a DeleteGlobal bytecode
    3552             :         // that knows how to deal with ScriptContexts as well as global
    3553             :         // object properties.
    3554             :         case VariableLocation::LOOKUP: {
    3555         675 :           Register name_reg = register_allocator()->NewRegister();
    3556             :           builder()
    3557         675 :               ->LoadLiteral(variable->raw_name())
    3558         675 :               .StoreAccumulatorInRegister(name_reg)
    3559         675 :               .CallRuntime(Runtime::kDeleteLookupSlot, name_reg);
    3560             :           break;
    3561             :         }
    3562             :         default:
    3563           0 :           UNREACHABLE();
    3564             :       }
    3565             :     }
    3566             :   } else {
    3567             :     // Delete of an unresolvable reference returns true.
    3568         467 :     VisitForEffect(expr->expression());
    3569         467 :     builder()->LoadTrue();
    3570             :   }
    3571       10910 : }
    3572             : 
    3573     1635494 : void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
    3574             :   DCHECK(expr->expression()->IsValidReferenceExpression());
    3575             : 
    3576             :   // Left-hand side can only be a property, a global or a variable slot.
    3577      222791 :   Property* property = expr->expression()->AsProperty();
    3578      204333 :   LhsKind assign_type = Property::GetAssignType(property);
    3579             : 
    3580      360615 :   bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
    3581             : 
    3582             :   // Evaluate LHS expression and get old value.
    3583             :   Register object, key, old_value;
    3584             :   RegisterList super_property_args;
    3585             :   const AstRawString* name;
    3586      204333 :   switch (assign_type) {
    3587             :     case VARIABLE: {
    3588      585312 :       VariableProxy* proxy = expr->expression()->AsVariableProxy();
    3589             :       BuildVariableLoadForAccumulatorValue(proxy->var(),
    3590      195104 :                                            proxy->hole_check_mode());
    3591      195104 :       break;
    3592             :     }
    3593             :     case NAMED_PROPERTY: {
    3594        8317 :       object = VisitForRegisterValue(property->obj());
    3595       16634 :       name = property->key()->AsLiteral()->AsRawPropertyName();
    3596             :       builder()->LoadNamedProperty(
    3597       16634 :           object, name, feedback_index(feedback_spec()->AddLoadICSlot()));
    3598        8317 :       break;
    3599             :     }
    3600             :     case KEYED_PROPERTY: {
    3601         774 :       object = VisitForRegisterValue(property->obj());
    3602             :       // Use visit for accumulator here since we need the key in the accumulator
    3603             :       // for the LoadKeyedProperty.
    3604         774 :       key = register_allocator()->NewRegister();
    3605         774 :       VisitForAccumulatorValue(property->key());
    3606         774 :       builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
    3607        1548 :           object, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
    3608         774 :       break;
    3609             :     }
    3610             :     case NAMED_SUPER_PROPERTY: {
    3611          46 :       super_property_args = register_allocator()->NewRegisterList(4);
    3612          46 :       RegisterList load_super_args = super_property_args.Truncate(3);
    3613          92 :       SuperPropertyReference* super_property =
    3614          46 :           property->obj()->AsSuperPropertyReference();
    3615             :       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
    3616             :       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
    3617             :       builder()
    3618         138 :           ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
    3619          46 :           .StoreAccumulatorInRegister(load_super_args[2])
    3620          46 :           .CallRuntime(Runtime::kLoadFromSuper, load_super_args);
    3621             :       break;
    3622             :     }
    3623             :     case KEYED_SUPER_PROPERTY: {
    3624          92 :       super_property_args = register_allocator()->NewRegisterList(4);
    3625          92 :       RegisterList load_super_args = super_property_args.Truncate(3);
    3626         184 :       SuperPropertyReference* super_property =
    3627          92 :           property->obj()->AsSuperPropertyReference();
    3628             :       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
    3629             :       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
    3630             :       VisitForRegisterValue(property->key(), load_super_args[2]);
    3631          92 :       builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, load_super_args);
    3632             :       break;
    3633             :     }
    3634             :   }
    3635             : 
    3636             :   // Save result for postfix expressions.
    3637      204333 :   FeedbackSlot count_slot = feedback_spec()->AddBinaryOpICSlot();
    3638      204333 :   if (is_postfix) {
    3639       29055 :     old_value = register_allocator()->NewRegister();
    3640             :     // Convert old value into a number before saving it.
    3641             :     // TODO(ignition): Think about adding proper PostInc/PostDec bytecodes
    3642             :     // instead of this ToNumber + Inc/Dec dance.
    3643             :     builder()
    3644       29055 :         ->ToNumeric(feedback_index(count_slot))
    3645       29055 :         .StoreAccumulatorInRegister(old_value);
    3646             :   }
    3647             : 
    3648             :   // Perform +1/-1 operation.
    3649      204333 :   builder()->UnaryOperation(expr->op(), feedback_index(count_slot));
    3650             : 
    3651             :   // Store the value.
    3652             :   builder()->SetExpressionPosition(expr);
    3653      204333 :   switch (assign_type) {
    3654             :     case VARIABLE: {
    3655      585312 :       VariableProxy* proxy = expr->expression()->AsVariableProxy();
    3656             :       BuildVariableAssignment(proxy->var(), expr->op(),
    3657      195104 :                               proxy->hole_check_mode());
    3658      195104 :       break;
    3659             :     }
    3660             :     case NAMED_PROPERTY: {
    3661        8317 :       FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
    3662             :       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    3663        8317 :                                     language_mode());
    3664             :       break;
    3665             :     }
    3666             :     case KEYED_PROPERTY: {
    3667         774 :       FeedbackSlot slot = feedback_spec()->AddKeyedStoreICSlot(language_mode());
    3668             :       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    3669         774 :                                     language_mode());
    3670             :       break;
    3671             :     }
    3672             :     case NAMED_SUPER_PROPERTY: {
    3673             :       builder()
    3674          46 :           ->StoreAccumulatorInRegister(super_property_args[3])
    3675          46 :           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
    3676          46 :       break;
    3677             :     }
    3678             :     case KEYED_SUPER_PROPERTY: {
    3679             :       builder()
    3680          92 :           ->StoreAccumulatorInRegister(super_property_args[3])
    3681          92 :           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
    3682          92 :       break;
    3683             :     }
    3684             :   }
    3685             : 
    3686             :   // Restore old value for postfix expressions.
    3687      204333 :   if (is_postfix) {
    3688       29055 :     builder()->LoadAccumulatorWithRegister(old_value);
    3689             :   }
    3690      204333 : }
    3691             : 
    3692     1163699 : void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
    3693     1163699 :   switch (binop->op()) {
    3694             :     case Token::COMMA:
    3695      109343 :       VisitCommaExpression(binop);
    3696      109343 :       break;
    3697             :     case Token::OR:
    3698      147247 :       VisitLogicalOrExpression(binop);
    3699      147247 :       break;
    3700             :     case Token::AND:
    3701      140625 :       VisitLogicalAndExpression(binop);
    3702      140625 :       break;
    3703             :     default:
    3704      766484 :       VisitArithmeticExpression(binop);
    3705      766484 :       break;
    3706             :   }
    3707     1163699 : }
    3708             : 
    3709      268858 : void BytecodeGenerator::BuildLiteralCompareNil(Token::Value op, NilValue nil) {
    3710      134429 :   if (execution_result()->IsTest()) {
    3711      245180 :     TestResultScope* test_result = execution_result()->AsTest();
    3712      122590 :     switch (test_result->fallthrough()) {
    3713             :       case TestFallthrough::kThen:
    3714       78567 :         builder()->JumpIfNotNil(test_result->NewElseLabel(), op, nil);
    3715       78567 :         break;
    3716             :       case TestFallthrough::kElse:
    3717       44023 :         builder()->JumpIfNil(test_result->NewThenLabel(), op, nil);
    3718       44023 :         break;
    3719             :       case TestFallthrough::kNone:
    3720             :         builder()
    3721           0 :             ->JumpIfNil(test_result->NewThenLabel(), op, nil)
    3722           0 :             .Jump(test_result->NewElseLabel());
    3723             :     }
    3724             :     test_result->SetResultConsumedByTest();
    3725             :   } else {
    3726       11839 :     builder()->CompareNil(op, nil);
    3727             :   }
    3728      134429 : }
    3729             : 
    3730     8296015 : void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
    3731             :   Expression* sub_expr;
    3732             :   Literal* literal;
    3733     1162365 :   if (expr->IsLiteralCompareTypeof(&sub_expr, &literal)) {
    3734             :     // Emit a fast literal comparion for expressions of the form:
    3735             :     // typeof(x) === 'string'.
    3736      145602 :     VisitForTypeOfValue(sub_expr);
    3737             :     builder()->SetExpressionPosition(expr);
    3738             :     TestTypeOfFlags::LiteralFlag literal_flag =
    3739      291204 :         TestTypeOfFlags::GetFlagForLiteral(ast_string_constants(), literal);
    3740      145602 :     if (literal_flag == TestTypeOfFlags::LiteralFlag::kOther) {
    3741         228 :       builder()->LoadFalse();
    3742             :     } else {
    3743      145374 :       builder()->CompareTypeOf(literal_flag);
    3744             :     }
    3745     1016763 :   } else if (expr->IsLiteralCompareUndefined(&sub_expr)) {
    3746       79695 :     VisitForAccumulatorValue(sub_expr);
    3747             :     builder()->SetExpressionPosition(expr);
    3748       79695 :     BuildLiteralCompareNil(expr->op(), kUndefinedValue);
    3749      937068 :   } else if (expr->IsLiteralCompareNull(&sub_expr)) {
    3750       54734 :     VisitForAccumulatorValue(sub_expr);
    3751             :     builder()->SetExpressionPosition(expr);
    3752       54734 :     BuildLiteralCompareNil(expr->op(), kNullValue);
    3753             :   } else {
    3754      882334 :     Register lhs = VisitForRegisterValue(expr->left());
    3755      882334 :     VisitForAccumulatorValue(expr->right());
    3756             :     builder()->SetExpressionPosition(expr);
    3757      882334 :     if (expr->op() == Token::INSTANCEOF || expr->op() == Token::IN) {
    3758       28383 :       builder()->CompareOperation(expr->op(), lhs);
    3759             :     } else {
    3760      853951 :       FeedbackSlot slot = feedback_spec()->AddCompareICSlot();
    3761      853951 :       builder()->CompareOperation(expr->op(), lhs, feedback_index(slot));
    3762             :     }
    3763             :   }
    3764             :   // Always returns a boolean value.
    3765             :   execution_result()->SetResultIsBoolean();
    3766     1162365 : }
    3767             : 
    3768     4236067 : void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
    3769      766484 :   FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot();
    3770             :   Expression* subexpr;
    3771             :   Smi* literal;
    3772      766484 :   if (expr->IsSmiLiteralOperation(&subexpr, &literal)) {
    3773      181417 :     VisitForAccumulatorValue(subexpr);
    3774             :     builder()->SetExpressionPosition(expr);
    3775             :     builder()->BinaryOperationSmiLiteral(expr->op(), literal,
    3776      362834 :                                          feedback_index(slot));
    3777             :   } else {
    3778      585067 :     Register lhs = VisitForRegisterValue(expr->left());
    3779      585067 :     VisitForAccumulatorValue(expr->right());
    3780             :     builder()->SetExpressionPosition(expr);
    3781      585066 :     builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
    3782             :   }
    3783      766484 : }
    3784             : 
    3785        4462 : void BytecodeGenerator::VisitSpread(Spread* expr) { Visit(expr->expression()); }
    3786             : 
    3787           0 : void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
    3788           0 :   UNREACHABLE();
    3789             : }
    3790             : 
    3791         696 : void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
    3792         232 :   RegisterList args = register_allocator()->NewRegisterList(2);
    3793             :   VisitForRegisterValue(expr->argument(), args[1]);
    3794             :   builder()
    3795         464 :       ->MoveRegister(Register::function_closure(), args[0])
    3796         232 :       .CallRuntime(Runtime::kDynamicImportCall, args);
    3797         232 : }
    3798             : 
    3799       26721 : void BytecodeGenerator::BuildGetIterator(Expression* iterable,
    3800      135915 :                                          IteratorType hint) {
    3801       26721 :   RegisterList args = register_allocator()->NewRegisterList(1);
    3802       26721 :   Register method = register_allocator()->NewRegister();
    3803       26721 :   Register obj = args[0];
    3804             : 
    3805       26721 :   VisitForAccumulatorValue(iterable);
    3806             : 
    3807       26721 :   if (hint == IteratorType::kAsync) {
    3808             :     // Set method to GetMethod(obj, @@asyncIterator)
    3809         330 :     builder()->StoreAccumulatorInRegister(obj).LoadAsyncIteratorProperty(
    3810         660 :         obj, feedback_index(feedback_spec()->AddLoadICSlot()));
    3811             : 
    3812             :     BytecodeLabel async_iterator_undefined, async_iterator_null, done;
    3813             :     // TODO(ignition): Add a single opcode for JumpIfNullOrUndefined
    3814         330 :     builder()->JumpIfUndefined(&async_iterator_undefined);
    3815         330 :     builder()->JumpIfNull(&async_iterator_null);
    3816             : 
    3817             :     // Let iterator be Call(method, obj)
    3818         330 :     builder()->StoreAccumulatorInRegister(method).CallProperty(
    3819         660 :         method, args, feedback_index(feedback_spec()->AddCallICSlot()));
    3820             : 
    3821             :     // If Type(iterator) is not Object, throw a TypeError exception.
    3822         330 :     builder()->JumpIfJSReceiver(&done);
    3823         330 :     builder()->CallRuntime(Runtime::kThrowSymbolAsyncIteratorInvalid);
    3824             : 
    3825         330 :     builder()->Bind(&async_iterator_undefined);
    3826         330 :     builder()->Bind(&async_iterator_null);
    3827             :     // If method is undefined,
    3828             :     //     Let syncMethod be GetMethod(obj, @@iterator)
    3829             :     builder()
    3830             :         ->LoadIteratorProperty(obj,
    3831         660 :                                feedback_index(feedback_spec()->AddLoadICSlot()))
    3832         330 :         .StoreAccumulatorInRegister(method);
    3833             : 
    3834             :     //     Let syncIterator be Call(syncMethod, obj)
    3835             :     builder()->CallProperty(method, args,
    3836         660 :                             feedback_index(feedback_spec()->AddCallICSlot()));
    3837             : 
    3838             :     // Return CreateAsyncFromSyncIterator(syncIterator)
    3839             :     // alias `method` register as it's no longer used
    3840         330 :     Register sync_iter = method;
    3841         330 :     builder()->StoreAccumulatorInRegister(sync_iter).CallRuntime(
    3842         330 :         Runtime::kInlineCreateAsyncFromSyncIterator, sync_iter);
    3843             : 
    3844         330 :     builder()->Bind(&done);
    3845             :   } else {
    3846             :     // Let method be GetMethod(obj, @@iterator).
    3847             :     builder()
    3848       26391 :         ->StoreAccumulatorInRegister(obj)
    3849             :         .LoadIteratorProperty(obj,
    3850       52782 :                               feedback_index(feedback_spec()->AddLoadICSlot()))
    3851       26391 :         .StoreAccumulatorInRegister(method);
    3852             : 
    3853             :     // Let iterator be Call(method, obj).
    3854             :     builder()->CallProperty(method, args,
    3855       52782 :                             feedback_index(feedback_spec()->AddCallICSlot()));
    3856             : 
    3857             :     // If Type(iterator) is not Object, throw a TypeError exception.
    3858             :     BytecodeLabel no_type_error;
    3859       26391 :     builder()->JumpIfJSReceiver(&no_type_error);
    3860       26391 :     builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid);
    3861       26391 :     builder()->Bind(&no_type_error);
    3862             :   }
    3863       26721 : }
    3864             : 
    3865       52956 : void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
    3866             :   builder()->SetExpressionPosition(expr);
    3867       26478 :   BuildGetIterator(expr->iterable(), expr->hint());
    3868       26478 : }
    3869             : 
    3870        4317 : void BytecodeGenerator::VisitGetTemplateObject(GetTemplateObject* expr) {
    3871             :   builder()->SetExpressionPosition(expr);
    3872        1439 :   size_t entry = builder()->AllocateDeferredConstantPoolEntry();
    3873        2878 :   template_objects_.push_back(std::make_pair(expr, entry));
    3874        1439 :   builder()->GetTemplateObject(entry);
    3875        1439 : }
    3876             : 
    3877       68806 : void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
    3878      137612 :   builder()->LoadAccumulatorWithRegister(Register::function_closure());
    3879           0 : }
    3880             : 
    3881           0 : void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
    3882             :   // Handled by VisitCall().
    3883           0 :   UNREACHABLE();
    3884             : }
    3885             : 
    3886           0 : void BytecodeGenerator::VisitSuperPropertyReference(
    3887          18 :     SuperPropertyReference* expr) {
    3888          18 :   builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
    3889           0 : }
    3890             : 
    3891      218686 : void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
    3892      109343 :   VisitForEffect(binop->left());
    3893      109343 :   Visit(binop->right());
    3894      109343 : }
    3895             : 
    3896      178351 : void BytecodeGenerator::BuildLogicalTest(Token::Value token, Expression* left,
    3897      535053 :                                          Expression* right) {
    3898             :   DCHECK(token == Token::OR || token == Token::AND);
    3899      178351 :   TestResultScope* test_result = execution_result()->AsTest();
    3900             :   BytecodeLabels* then_labels = test_result->then_labels();
    3901             :   BytecodeLabels* else_labels = test_result->else_labels();
    3902             :   TestFallthrough fallthrough = test_result->fallthrough();
    3903             :   {
    3904             :     // Visit the left side using current TestResultScope.
    3905             :     BytecodeLabels test_right(zone());
    3906      178351 :     if (token == Token::OR) {
    3907             :       test_result->set_fallthrough(TestFallthrough::kElse);
    3908             :       test_result->set_else_labels(&test_right);
    3909             :     } else {
    3910             :       DCHECK_EQ(Token::AND, token);
    3911             :       test_result->set_fallthrough(TestFallthrough::kThen);
    3912             :       test_result->set_then_labels(&test_right);
    3913             :     }
    3914      178351 :     VisitInSameTestExecutionScope(left);
    3915      178351 :     test_right.Bind(builder());
    3916             :   }
    3917             :   // Visit the right side in a new TestResultScope.
    3918      178351 :   VisitForTest(right, then_labels, else_labels, fallthrough);
    3919      178351 : }
    3920             : 
    3921      213174 : void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
    3922             :   Expression* left = binop->left();
    3923             :   Expression* right = binop->right();
    3924             : 
    3925      147247 :   if (execution_result()->IsTest()) {
    3926        4341 :     TestResultScope* test_result = execution_result()->AsTest();
    3927      114624 :     if (left->ToBooleanIsTrue()) {
    3928        4341 :       builder()->Jump(test_result->NewThenLabel());
    3929      110283 :     } else if (left->ToBooleanIsFalse() && right->ToBooleanIsFalse()) {
    3930           0 :       builder()->Jump(test_result->NewElseLabel());
    3931             :     } else {
    3932      110283 :       BuildLogicalTest(Token::OR, left, right);
    3933             :     }
    3934             :     test_result->SetResultConsumedByTest();
    3935             :   } else {
    3936       32623 :     if (left->ToBooleanIsTrue()) {
    3937        1683 :       VisitForAccumulatorValue(left);
    3938       30940 :     } else if (left->ToBooleanIsFalse()) {
    3939         147 :       VisitForAccumulatorValue(right);
    3940             :     } else {
    3941             :       BytecodeLabel end_label;
    3942       30793 :       TypeHint type_hint = VisitForAccumulatorValue(left);
    3943       30793 :       builder()->JumpIfTrue(ToBooleanModeFromTypeHint(type_hint), &end_label);
    3944       30793 :       VisitForAccumulatorValue(right);
    3945       30793 :       builder()->Bind(&end_label);
    3946             :     }
    3947             :   }
    3948      147247 : }
    3949             : 
    3950      282042 : void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
    3951             :   Expression* left = binop->left();
    3952             :   Expression* right = binop->right();
    3953             : 
    3954      140625 :   if (execution_result()->IsTest()) {
    3955           5 :     TestResultScope* test_result = execution_result()->AsTest();
    3956       68073 :     if (left->ToBooleanIsFalse()) {
    3957           5 :       builder()->Jump(test_result->NewElseLabel());
    3958       68068 :     } else if (left->ToBooleanIsTrue() && right->ToBooleanIsTrue()) {
    3959           0 :       builder()->Jump(test_result->NewThenLabel());
    3960             :     } else {
    3961       68068 :       BuildLogicalTest(Token::AND, left, right);
    3962             :     }
    3963             :     test_result->SetResultConsumedByTest();
    3964             :   } else {
    3965       72552 :     if (left->ToBooleanIsFalse()) {
    3966         147 :       VisitForAccumulatorValue(left);
    3967       72405 :     } else if (left->ToBooleanIsTrue()) {
    3968        1699 :       VisitForAccumulatorValue(right);
    3969             :     } else {
    3970             :       BytecodeLabel end_label;
    3971       70706 :       TypeHint type_hint = VisitForAccumulatorValue(left);
    3972       70706 :       builder()->JumpIfFalse(ToBooleanModeFromTypeHint(type_hint), &end_label);
    3973       70706 :       VisitForAccumulatorValue(right);
    3974       70706 :       builder()->Bind(&end_label);
    3975             :     }
    3976             :   }
    3977      140625 : }
    3978             : 
    3979        1354 : void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
    3980        1354 :   Visit(expr->expression());
    3981        1354 : }
    3982             : 
    3983      361844 : void BytecodeGenerator::BuildNewLocalActivationContext() {
    3984             :   ValueResultScope value_execution_result(this);
    3985      343459 :   Scope* scope = closure_scope();
    3986             : 
    3987             :   // Create the appropriate context.
    3988      176056 :   if (scope->is_script_scope()) {
    3989        7592 :     RegisterList args = register_allocator()->NewRegisterList(2);
    3990             :     builder()
    3991       15184 :         ->LoadAccumulatorWithRegister(Register::function_closure())
    3992        7592 :         .StoreAccumulatorInRegister(args[0])
    3993        7592 :         .LoadLiteral(scope)
    3994        7592 :         .StoreAccumulatorInRegister(args[1])
    3995        7592 :         .CallRuntime(Runtime::kNewScriptContext, args);
    3996      168464 :   } else if (scope->is_module_scope()) {
    3997             :     // We don't need to do anything for the outer script scope.
    3998             :     DCHECK(scope->outer_scope()->is_script_scope());
    3999             : 
    4000             :     // A JSFunction representing a module is called with the module object as
    4001             :     // its sole argument, which we pass on to PushModuleContext.
    4002        1067 :     RegisterList args = register_allocator()->NewRegisterList(3);
    4003             :     builder()
    4004        2134 :         ->MoveRegister(builder()->Parameter(0), args[0])
    4005        2134 :         .LoadAccumulatorWithRegister(Register::function_closure())
    4006        1067 :         .StoreAccumulatorInRegister(args[1])
    4007        1067 :         .LoadLiteral(scope)
    4008        1067 :         .StoreAccumulatorInRegister(args[2])
    4009        1067 :         .CallRuntime(Runtime::kPushModuleContext, args);
    4010             :   } else {
    4011             :     DCHECK(scope->is_function_scope() || scope->is_eval_scope());
    4012      167397 :     int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
    4013      167397 :     if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) {
    4014      167391 :       switch (scope->scope_type()) {
    4015             :         case EVAL_SCOPE:
    4016       20739 :           builder()->CreateEvalContext(slot_count);
    4017       20739 :           break;
    4018             :         case FUNCTION_SCOPE:
    4019      146652 :           builder()->CreateFunctionContext(slot_count);
    4020      146652 :           break;
    4021             :         default:
    4022           0 :           UNREACHABLE();
    4023             :       }
    4024             :     } else {
    4025           6 :       RegisterList args = register_allocator()->NewRegisterList(2);
    4026             :       builder()
    4027          12 :           ->MoveRegister(Register::function_closure(), args[0])
    4028           6 :           .LoadLiteral(Smi::FromInt(scope->scope_type()))
    4029           6 :           .StoreAccumulatorInRegister(args[1])
    4030           6 :           .CallRuntime(Runtime::kNewFunctionContext, args);
    4031             :     }
    4032             :   }
    4033      176056 : }
    4034             : 
    4035      488216 : void BytecodeGenerator::BuildLocalActivationContextInitialization() {
    4036      242584 :   DeclarationScope* scope = closure_scope();
    4037             : 
    4038      320325 :   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
    4039       98315 :     Variable* variable = scope->receiver();
    4040       98315 :     Register receiver(builder()->Receiver());
    4041             :     // Context variable (at bottom of the context chain).
    4042             :     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
    4043       98315 :     builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
    4044       98315 :         execution_context()->reg(), variable->index(), 0);
    4045             :   }
    4046             : 
    4047             :   // Copy parameters into context if necessary.
    4048             :   int num_parameters = scope->num_parameters();
    4049      293807 :   for (int i = 0; i < num_parameters; i++) {
    4050       57765 :     Variable* variable = scope->parameter(i);
    4051      177737 :     if (!variable->IsContextSlot()) continue;
    4052             : 
    4053       57765 :     Register parameter(builder()->Parameter(i));
    4054             :     // Context variable (at bottom of the context chain).
    4055             :     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
    4056       57765 :     builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
    4057       57765 :         execution_context()->reg(), variable->index(), 0);
    4058             :   }
    4059      176056 : }
    4060             : 
    4061      113062 : void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) {
    4062             :   ValueResultScope value_execution_result(this);
    4063             :   DCHECK(scope->is_block_scope());
    4064             : 
    4065       56531 :   VisitFunctionClosureForContext();
    4066       56531 :   builder()->CreateBlockContext(scope);
    4067       56531 : }
    4068             : 
    4069        9072 : void BytecodeGenerator::BuildNewLocalWithContext(Scope* scope) {
    4070             :   ValueResultScope value_execution_result(this);
    4071             : 
    4072        3024 :   Register extension_object = register_allocator()->NewRegister();
    4073             : 
    4074        3024 :   builder()->ToObject(extension_object);
    4075        3024 :   VisitFunctionClosureForContext();
    4076        3024 :   builder()->CreateWithContext(extension_object, scope);
    4077        3024 : }
    4078             : 
    4079      306366 : void BytecodeGenerator::BuildNewLocalCatchContext(Scope* scope) {
    4080             :   ValueResultScope value_execution_result(this);
    4081             :   DCHECK(scope->catch_variable()->IsContextSlot());
    4082             : 
    4083      102122 :   Register exception = register_allocator()->NewRegister();
    4084      102122 :   builder()->StoreAccumulatorInRegister(exception);
    4085      102122 :   VisitFunctionClosureForContext();
    4086             :   builder()->CreateCatchContext(exception, scope->catch_variable()->raw_name(),
    4087      204244 :                                 scope);
    4088      102122 : }
    4089             : 
    4090        8000 : void BytecodeGenerator::VisitObjectLiteralAccessor(
    4091        3420 :     Register home_object, ObjectLiteralProperty* property, Register value_out) {
    4092        8000 :   if (property == nullptr) {
    4093        3420 :     builder()->LoadNull().StoreAccumulatorInRegister(value_out);
    4094             :   } else {
    4095        4580 :     VisitForRegisterValue(property->value(), value_out);
    4096        4580 :     VisitSetHomeObject(value_out, home_object, property);
    4097             :   }
    4098        8000 : }
    4099             : 
    4100      406223 : void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
    4101      525364 :                                            LiteralProperty* property) {
    4102             :   Expression* expr = property->value();
    4103      406223 :   if (FunctionLiteral::NeedsHomeObject(expr)) {
    4104      119141 :     FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
    4105             :     builder()
    4106      119141 :         ->LoadAccumulatorWithRegister(home_object)
    4107      119141 :         .StoreHomeObjectProperty(value, feedback_index(slot), language_mode());
    4108             :   }
    4109      406223 : }
    4110             : 
    4111     2284219 : void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
    4112     4262642 :   if (variable == nullptr) return;
    4113             : 
    4114             :   DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
    4115             : 
    4116             :   // Allocate and initialize a new arguments object and assign to the
    4117             :   // {arguments} variable.
    4118             :   CreateArgumentsType type =
    4119       57204 :       is_strict(language_mode()) || !info()->has_simple_parameters()
    4120             :           ? CreateArgumentsType::kUnmappedArguments
    4121       95694 :           : CreateArgumentsType::kMappedArguments;
    4122       95694 :   builder()->CreateArguments(type);
    4123       95694 :   BuildVariableAssignment(variable, Token::ASSIGN, HoleCheckMode::kElided);
    4124             : }
    4125             : 
    4126     2135316 : void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
    4127     4262646 :   if (rest == nullptr) return;
    4128             : 
    4129             :   // Allocate and initialize a new rest parameter and assign to the {rest}
    4130             :   // variable.
    4131        3993 :   builder()->CreateArguments(CreateArgumentsType::kRestParameter);
    4132             :   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
    4133        3993 :   BuildVariableAssignment(rest, Token::ASSIGN, HoleCheckMode::kElided);
    4134             : }
    4135             : 
    4136     2139411 : void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
    4137     4262646 :   if (variable == nullptr) return;
    4138             : 
    4139             :   // Store the closure we were called with in the given variable.
    4140       16176 :   builder()->LoadAccumulatorWithRegister(Register::function_closure());
    4141        8088 :   BuildVariableAssignment(variable, Token::INIT, HoleCheckMode::kElided);
    4142             : }
    4143             : 
    4144     2426005 : void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
    4145     2131321 :   if (variable == nullptr) return;
    4146             : 
    4147             :   // The generator resume trampoline abuses the new.target register
    4148             :   // to pass in the generator object.  In ordinary calls, new.target is always
    4149             :   // undefined because generator functions are non-constructible, so don't
    4150             :   // assign anything to the new.target variable.
    4151      206350 :   if (info()->literal()->CanSuspend()) return;
    4152             : 
    4153      102885 :   if (variable->location() == VariableLocation::LOCAL) {
    4154             :     // The new.target register was already assigned by entry trampoline.
    4155             :     DCHECK_EQ(incoming_new_target_or_generator_.index(),
    4156             :               GetRegisterForLocalVariable(variable).index());
    4157             :     return;
    4158             :   }
    4159             : 
    4160             :   // Store the new target we were called with in the given variable.
    4161       88624 :   builder()->LoadAccumulatorWithRegister(incoming_new_target_or_generator_);
    4162       88624 :   BuildVariableAssignment(variable, Token::INIT, HoleCheckMode::kElided);
    4163             : }
    4164             : 
    4165       24858 : void BytecodeGenerator::BuildGeneratorObjectVariableInitialization() {
    4166             :   DCHECK(IsResumableFunction(info()->literal()->kind()));
    4167             : 
    4168        8286 :   Variable* generator_object_var = closure_scope()->generator_object_var();
    4169             :   RegisterAllocationScope register_scope(this);
    4170        8286 :   RegisterList args = register_allocator()->NewRegisterList(2);
    4171             :   builder()
    4172       16572 :       ->MoveRegister(Register::function_closure(), args[0])
    4173       16572 :       .MoveRegister(builder()->Receiver(), args[1])
    4174        8286 :       .CallRuntime(Runtime::kInlineCreateJSGeneratorObject, args)
    4175        8286 :       .StoreAccumulatorInRegister(generator_object());
    4176             : 
    4177        8286 :   if (generator_object_var->location() == VariableLocation::LOCAL) {
    4178             :     // The generator object register is already set to the variable's local
    4179             :     // register.
    4180             :     DCHECK_EQ(generator_object().index(),
    4181             :               GetRegisterForLocalVariable(generator_object_var).index());
    4182             :   } else {
    4183             :     BuildVariableAssignment(generator_object_var, Token::INIT,
    4184        1067 :                             HoleCheckMode::kElided);
    4185        8286 :   }
    4186        8286 : }
    4187             : 
    4188      485031 : void BytecodeGenerator::VisitFunctionClosureForContext() {
    4189             :   ValueResultScope value_execution_result(this);
    4190      161677 :   if (closure_scope()->is_script_scope()) {
    4191             :     // Contexts nested in the native context have a canonical empty function as
    4192             :     // their closure, not the anonymous closure containing the global code.
    4193       23293 :     Register native_context = register_allocator()->NewRegister();
    4194             :     builder()
    4195             :         ->LoadContextSlot(execution_context()->reg(),
    4196             :                           Context::NATIVE_CONTEXT_INDEX, 0,
    4197       23293 :                           BytecodeArrayBuilder::kImmutableSlot)
    4198       23293 :         .StoreAccumulatorInRegister(native_context)
    4199             :         .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0,
    4200       23293 :                          BytecodeArrayBuilder::kImmutableSlot);
    4201      138384 :   } else if (closure_scope()->is_eval_scope()) {
    4202             :     // Contexts created by a call to eval have the same closure as the
    4203             :     // context calling eval, not the anonymous closure containing the eval
    4204             :     // code. Fetch it from the context.
    4205             :     builder()->LoadContextSlot(execution_context()->reg(),
    4206             :                                Context::CLOSURE_INDEX, 0,
    4207       25494 :                                BytecodeArrayBuilder::kImmutableSlot);
    4208             :   } else {
    4209             :     DCHECK(closure_scope()->is_function_scope() ||
    4210             :            closure_scope()->is_module_scope());
    4211      225780 :     builder()->LoadAccumulatorWithRegister(Register::function_closure());
    4212             :   }
    4213      161677 : }
    4214             : 
    4215         596 : void BytecodeGenerator::BuildPushUndefinedIntoRegisterList(
    4216         596 :     RegisterList* reg_list) {
    4217         596 :   Register reg = register_allocator()->GrowRegisterList(reg_list);
    4218         596 :   builder()->LoadUndefined().StoreAccumulatorInRegister(reg);
    4219         596 : }
    4220             : 
    4221      801266 : void BytecodeGenerator::BuildLoadPropertyKey(LiteralProperty* property,
    4222        7237 :                                              Register out_reg) {
    4223      400633 :   if (property->key()->IsStringLiteral()) {
    4224             :     VisitForRegisterValue(property->key(), out_reg);
    4225             :   } else {
    4226        7237 :     VisitForAccumulatorValue(property->key());
    4227        7237 :     builder()->ToName(out_reg);
    4228             :   }
    4229      400633 : }
    4230             : 
    4231           0 : int BytecodeGenerator::AllocateBlockCoverageSlotIfEnabled(
    4232             :     AstNode* node, SourceRangeKind kind) {
    4233     2319529 :   return (block_coverage_builder_ == nullptr)
    4234             :              ? BlockCoverageBuilder::kNoCoverageArraySlot
    4235     2319529 :              : block_coverage_builder_->AllocateBlockCoverageSlot(node, kind);
    4236             : }
    4237             : 
    4238           0 : void BytecodeGenerator::BuildIncrementBlockCoverageCounterIfEnabled(
    4239             :     AstNode* node, SourceRangeKind kind) {
    4240      296892 :   if (block_coverage_builder_ == nullptr) return;
    4241         786 :   block_coverage_builder_->IncrementBlockCounter(node, kind);
    4242             : }
    4243             : 
    4244           0 : void BytecodeGenerator::BuildIncrementBlockCoverageCounterIfEnabled(
    4245             :     int coverage_array_slot) {
    4246           0 :   if (block_coverage_builder_ != nullptr) {
    4247             :     block_coverage_builder_->IncrementBlockCounter(coverage_array_slot);
    4248             :   }
    4249           0 : }
    4250             : 
    4251             : // Visits the expression |expr| and places the result in the accumulator.
    4252    18947646 : BytecodeGenerator::TypeHint BytecodeGenerator::VisitForAccumulatorValue(
    4253             :     Expression* expr) {
    4254             :   ValueResultScope accumulator_scope(this);
    4255    18947646 :   Visit(expr);
    4256    37895316 :   return accumulator_scope.type_hint();
    4257             : }
    4258             : 
    4259      112939 : void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
    4260       59344 :   if (expr == nullptr) {
    4261       53595 :     builder()->LoadTheHole();
    4262             :   } else {
    4263        5749 :     VisitForAccumulatorValue(expr);
    4264             :   }
    4265       59344 : }
    4266             : 
    4267             : // Visits the expression |expr| and discards the result.
    4268     9541607 : void BytecodeGenerator::VisitForEffect(Expression* expr) {
    4269             :   EffectResultScope effect_scope(this);
    4270     9541607 :   Visit(expr);
    4271     9541610 : }
    4272             : 
    4273             : // Visits the expression |expr| and returns the register containing
    4274             : // the expression result.
    4275    12517496 : Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
    4276     6258747 :   VisitForAccumulatorValue(expr);
    4277     6258749 :   Register result = register_allocator()->NewRegister();
    4278     6258749 :   builder()->StoreAccumulatorInRegister(result);
    4279     6258748 :   return result;
    4280             : }
    4281             : 
    4282             : // Visits the expression |expr| and stores the expression result in
    4283             : // |destination|.
    4284             : void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
    4285     1543408 :                                               Register destination) {
    4286     1543406 :   ValueResultScope register_scope(this);
    4287     1543406 :   Visit(expr);
    4288     1543408 :   builder()->StoreAccumulatorInRegister(destination);
    4289             : }
    4290             : 
    4291             : // Visits the expression |expr| and pushes the result into a new register
    4292             : // added to the end of |reg_list|.
    4293     8176847 : void BytecodeGenerator::VisitAndPushIntoRegisterList(Expression* expr,
    4294     8176848 :                                                      RegisterList* reg_list) {
    4295             :   {
    4296             :     ValueResultScope register_scope(this);
    4297     8176847 :     Visit(expr);
    4298             :   }
    4299             :   // Grow the register list after visiting the expression to avoid reserving
    4300             :   // the register across the expression evaluation, which could cause memory
    4301             :   // leaks for deep expressions due to dead objects being kept alive by pointers
    4302             :   // in registers.
    4303     8176848 :   Register destination = register_allocator()->GrowRegisterList(reg_list);
    4304     8176848 :   builder()->StoreAccumulatorInRegister(destination);
    4305     8176846 : }
    4306             : 
    4307     1229536 : void BytecodeGenerator::BuildTest(ToBooleanMode mode,
    4308             :                                   BytecodeLabels* then_labels,
    4309             :                                   BytecodeLabels* else_labels,
    4310     1229536 :                                   TestFallthrough fallthrough) {
    4311     1229536 :   switch (fallthrough) {
    4312             :     case TestFallthrough::kThen:
    4313     1803368 :       builder()->JumpIfFalse(mode, else_labels->New());
    4314      901684 :       break;
    4315             :     case TestFallthrough::kElse:
    4316      655704 :       builder()->JumpIfTrue(mode, then_labels->New());
    4317      327852 :       break;
    4318             :     case TestFallthrough::kNone:
    4319           0 :       builder()->JumpIfTrue(mode, then_labels->New());
    4320           0 :       builder()->Jump(else_labels->New());
    4321           0 :       break;
    4322             :   }
    4323     1229536 : }
    4324             : 
    4325             : // Visits the expression |expr| for testing its boolean value and jumping to the
    4326             : // |then| or |other| label depending on value and short-circuit semantics
    4327     1356473 : void BytecodeGenerator::VisitForTest(Expression* expr,
    4328             :                                      BytecodeLabels* then_labels,
    4329             :                                      BytecodeLabels* else_labels,
    4330             :                                      TestFallthrough fallthrough) {
    4331             :   bool result_consumed;
    4332             :   TypeHint type_hint;
    4333             :   {
    4334             :     // To make sure that all temporary registers are returned before generating
    4335             :     // jumps below, we ensure that the result scope is deleted before doing so.
    4336             :     // Dead registers might be materialized otherwise.
    4337             :     TestResultScope test_result(this, then_labels, else_labels, fallthrough);
    4338     1356473 :     Visit(expr);
    4339     1356472 :     result_consumed = test_result.result_consumed_by_test();
    4340     1356472 :     type_hint = test_result.type_hint();
    4341             :     // Labels and fallthrough might have been mutated, so update based on
    4342             :     // TestResultScope.
    4343     1356472 :     then_labels = test_result.then_labels();
    4344     1356472 :     else_labels = test_result.else_labels();
    4345     1356472 :     fallthrough = test_result.fallthrough();
    4346             :   }
    4347     1356472 :   if (!result_consumed) {
    4348             :     BuildTest(ToBooleanModeFromTypeHint(type_hint), then_labels, else_labels,
    4349      894424 :               fallthrough);
    4350             :   }
    4351     1356472 : }
    4352             : 
    4353      923478 : void BytecodeGenerator::VisitInSameTestExecutionScope(Expression* expr) {
    4354             :   DCHECK(execution_result()->IsTest());
    4355             :   {
    4356             :     RegisterAllocationScope reg_scope(this);
    4357      461739 :     Visit(expr);
    4358             :   }
    4359      461739 :   if (!execution_result()->AsTest()->result_consumed_by_test()) {
    4360      335112 :     TestResultScope* result_scope = execution_result()->AsTest();
    4361             :     BuildTest(ToBooleanModeFromTypeHint(result_scope->type_hint()),
    4362             :               result_scope->then_labels(), result_scope->else_labels(),
    4363      670224 :               result_scope->fallthrough());
    4364             :     result_scope->SetResultConsumedByTest();
    4365             :   }
    4366      461739 : }
    4367             : 
    4368      105146 : void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
    4369             :   DCHECK(scope->declarations()->is_empty());
    4370             :   CurrentScope current_scope(this, scope);
    4371      210292 :   ContextScope context_scope(this, scope);
    4372      105146 :   Visit(stmt);
    4373      105146 : }
    4374             : 
    4375       21480 : Register BytecodeGenerator::GetRegisterForLocalVariable(Variable* variable) {
    4376             :   DCHECK_EQ(VariableLocation::LOCAL, variable->location());
    4377       21480 :   return builder()->Local(variable->index());
    4378             : }
    4379             : 
    4380       23775 : FunctionKind BytecodeGenerator::function_kind() const {
    4381       23775 :   return info()->literal()->kind();
    4382             : }
    4383             : 
    4384     6085811 : LanguageMode BytecodeGenerator::language_mode() const {
    4385             :   return current_scope()->language_mode();
    4386             : }
    4387             : 
    4388             : Register BytecodeGenerator::generator_object() const {
    4389             :   DCHECK(info()->literal()->CanSuspend());
    4390             :   return incoming_new_target_or_generator_;
    4391             : }
    4392             : 
    4393    19398787 : FeedbackVectorSpec* BytecodeGenerator::feedback_spec() {
    4394             :   return info()->feedback_vector_spec();
    4395             : }
    4396             : 
    4397             : int BytecodeGenerator::feedback_index(FeedbackSlot slot) const {
    4398             :   DCHECK(!slot.IsInvalid());
    4399             :   return FeedbackVector::GetIndex(slot);
    4400             : }
    4401             : 
    4402     3897155 : FeedbackSlot BytecodeGenerator::GetCachedLoadGlobalICSlot(
    4403     6313418 :     TypeofMode typeof_mode, Variable* variable) {
    4404     3897155 :   FeedbackSlot slot = feedback_slot_cache()->Get(typeof_mode, variable);
    4405     3897155 :   if (!slot.IsInvalid()) {
    4406     1480892 :     return slot;
    4407             :   }
    4408     2416263 :   slot = feedback_spec()->AddLoadGlobalICSlot(typeof_mode);
    4409             :   feedback_slot_cache()->Put(typeof_mode, variable, slot);
    4410     2416263 :   return slot;
    4411             : }
    4412             : 
    4413     4157075 : FeedbackSlot BytecodeGenerator::GetCachedCreateClosureSlot(
    4414     8314148 :     FunctionLiteral* literal) {
    4415     4157075 :   FeedbackSlot slot = feedback_slot_cache()->Get(literal);
    4416     4157074 :   if (!slot.IsInvalid()) {
    4417           0 :     return slot;
    4418             :   }
    4419     4157074 :   slot = feedback_spec()->AddCreateClosureSlot();
    4420             :   feedback_slot_cache()->Put(literal, slot);
    4421     4157072 :   return slot;
    4422             : }
    4423             : 
    4424             : Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
    4425             :   return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
    4426         268 :                                     : Runtime::kStoreToSuper_Sloppy;
    4427             : }
    4428             : 
    4429             : Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
    4430             :   return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
    4431         433 :                                     : Runtime::kStoreKeyedToSuper_Sloppy;
    4432             : }
    4433             : 
    4434             : }  // namespace interpreter
    4435             : }  // namespace internal
    4436             : }  // namespace v8

Generated by: LCOV version 1.10