LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-array-builder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 415 447 92.8 %
Date: 2019-04-17 Functions: 301 322 93.5 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/interpreter/bytecode-array-builder.h"
       6             : 
       7             : #include "src/globals.h"
       8             : #include "src/interpreter/bytecode-array-writer.h"
       9             : #include "src/interpreter/bytecode-jump-table.h"
      10             : #include "src/interpreter/bytecode-label.h"
      11             : #include "src/interpreter/bytecode-node.h"
      12             : #include "src/interpreter/bytecode-register-optimizer.h"
      13             : #include "src/interpreter/bytecode-source-info.h"
      14             : #include "src/interpreter/interpreter-intrinsics.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/objects/smi.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace interpreter {
      21             : 
      22             : class RegisterTransferWriter final
      23             :     : public NON_EXPORTED_BASE(BytecodeRegisterOptimizer::BytecodeWriter),
      24             :       public NON_EXPORTED_BASE(ZoneObject) {
      25             :  public:
      26             :   RegisterTransferWriter(BytecodeArrayBuilder* builder) : builder_(builder) {}
      27           0 :   ~RegisterTransferWriter() override = default;
      28             : 
      29     3815146 :   void EmitLdar(Register input) override { builder_->OutputLdarRaw(input); }
      30             : 
      31    20391762 :   void EmitStar(Register output) override { builder_->OutputStarRaw(output); }
      32             : 
      33     1378166 :   void EmitMov(Register input, Register output) override {
      34     1378166 :     builder_->OutputMovRaw(input, output);
      35     1378163 :   }
      36             : 
      37             :  private:
      38             :   BytecodeArrayBuilder* builder_;
      39             : };
      40             : 
      41     2136497 : BytecodeArrayBuilder::BytecodeArrayBuilder(
      42             :     Zone* zone, int parameter_count, int locals_count,
      43             :     FeedbackVectorSpec* feedback_vector_spec,
      44             :     SourcePositionTableBuilder::RecordingMode source_position_mode)
      45             :     : zone_(zone),
      46             :       feedback_vector_spec_(feedback_vector_spec),
      47             :       bytecode_generated_(false),
      48             :       constant_array_builder_(zone),
      49             :       handler_table_builder_(zone),
      50             :       parameter_count_(parameter_count),
      51             :       local_register_count_(locals_count),
      52             :       register_allocator_(fixed_register_count()),
      53             :       bytecode_array_writer_(zone, &constant_array_builder_,
      54             :                              source_position_mode),
      55     4272977 :       register_optimizer_(nullptr) {
      56             :   DCHECK_GE(parameter_count_, 0);
      57             :   DCHECK_GE(local_register_count_, 0);
      58             : 
      59     2136487 :   if (FLAG_ignition_reo) {
      60             :     register_optimizer_ = new (zone) BytecodeRegisterOptimizer(
      61             :         zone, &register_allocator_, fixed_register_count(), parameter_count,
      62     2135956 :         new (zone) RegisterTransferWriter(this));
      63             :   }
      64     2136507 : }
      65             : 
      66     1472226 : Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
      67             :   DCHECK_GE(parameter_index, 0);
      68             :   // The parameter indices are shifted by 1 (receiver is the
      69             :   // first entry).
      70     1472226 :   return Register::FromParameterIndex(parameter_index + 1, parameter_count());
      71             : }
      72             : 
      73     2535645 : Register BytecodeArrayBuilder::Receiver() const {
      74     2535645 :   return Register::FromParameterIndex(0, parameter_count());
      75             : }
      76             : 
      77     4898077 : Register BytecodeArrayBuilder::Local(int index) const {
      78             :   // TODO(marja): Make a DCHECK once crbug.com/706234 is fixed.
      79     4898077 :   CHECK_LT(index, locals_count());
      80     4898077 :   return Register(index);
      81             : }
      82             : 
      83     2111474 : Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
      84             :   DCHECK(RemainderOfBlockIsDead());
      85             :   DCHECK(!bytecode_generated_);
      86     2111474 :   bytecode_generated_ = true;
      87             : 
      88             :   int register_count = total_register_count();
      89             : 
      90     2111474 :   if (register_optimizer_) {
      91     2110946 :     register_optimizer_->Flush();
      92     2110954 :     register_count = register_optimizer_->maxiumum_register_index() + 1;
      93             :   }
      94             : 
      95             :   Handle<ByteArray> handler_table =
      96     2111482 :       handler_table_builder()->ToHandlerTable(isolate);
      97             :   return bytecode_array_writer_.ToBytecodeArray(
      98     2111466 :       isolate, register_count, parameter_count(), handler_table);
      99             : }
     100             : 
     101             : BytecodeSourceInfo BytecodeArrayBuilder::CurrentSourcePosition(
     102             :     Bytecode bytecode) {
     103             :   BytecodeSourceInfo source_position;
     104    88758590 :   if (latest_source_info_.is_valid()) {
     105             :     // Statement positions need to be emitted immediately.  Expression
     106             :     // positions can be pushed back until a bytecode is found that can
     107             :     // throw (if expression position filtering is turned on). We only
     108             :     // invalidate the existing source position information if it is used.
     109    60894100 :     if (latest_source_info_.is_statement() ||
     110    60936116 :         !FLAG_ignition_filter_expression_positions ||
     111             :         !Bytecodes::IsWithoutExternalSideEffects(bytecode)) {
     112    32534865 :       source_position = latest_source_info_;
     113             :       latest_source_info_.set_invalid();
     114             :     }
     115             :   }
     116             :   return source_position;
     117             : }
     118             : 
     119           0 : void BytecodeArrayBuilder::SetDeferredSourceInfo(
     120             :     BytecodeSourceInfo source_info) {
     121    34042145 :   if (!source_info.is_valid()) return;
     122     3485762 :   deferred_source_info_ = source_info;
     123             : }
     124             : 
     125           0 : void BytecodeArrayBuilder::AttachOrEmitDeferredSourceInfo(BytecodeNode* node) {
     126    80287545 :   if (!deferred_source_info_.is_valid()) return;
     127     3479436 :   if (!node->source_info().is_valid()) {
     128             :     node->set_source_info(deferred_source_info_);
     129      423486 :   } else if (deferred_source_info_.is_statement() &&
     130             :              node->source_info().is_expression()) {
     131             :     BytecodeSourceInfo source_position = node->source_info();
     132             :     source_position.MakeStatementPosition(source_position.source_position());
     133             :     node->set_source_info(source_position);
     134             :   }
     135             :   deferred_source_info_.set_invalid();
     136             : }
     137             : 
     138    78167061 : void BytecodeArrayBuilder::Write(BytecodeNode* node) {
     139             :   AttachOrEmitDeferredSourceInfo(node);
     140    78167061 :   bytecode_array_writer_.Write(node);
     141    78164190 : }
     142             : 
     143     1837927 : void BytecodeArrayBuilder::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
     144             :   AttachOrEmitDeferredSourceInfo(node);
     145     1837927 :   bytecode_array_writer_.WriteJump(node, label);
     146     1837917 : }
     147             : 
     148      262328 : void BytecodeArrayBuilder::WriteJumpLoop(BytecodeNode* node,
     149             :                                          BytecodeLoopHeader* loop_header) {
     150             :   AttachOrEmitDeferredSourceInfo(node);
     151      262328 :   bytecode_array_writer_.WriteJumpLoop(node, loop_header);
     152      262340 : }
     153             : 
     154       20229 : void BytecodeArrayBuilder::WriteSwitch(BytecodeNode* node,
     155             :                                        BytecodeJumpTable* jump_table) {
     156             :   AttachOrEmitDeferredSourceInfo(node);
     157       20229 :   bytecode_array_writer_.WriteSwitch(node, jump_table);
     158       20229 : }
     159             : 
     160     3815146 : void BytecodeArrayBuilder::OutputLdarRaw(Register reg) {
     161     3815146 :   uint32_t operand = static_cast<uint32_t>(reg.ToOperand());
     162             :   BytecodeNode node(BytecodeNode::Ldar(BytecodeSourceInfo(), operand));
     163     3815146 :   Write(&node);
     164     3815168 : }
     165             : 
     166    20391755 : void BytecodeArrayBuilder::OutputStarRaw(Register reg) {
     167    20391755 :   uint32_t operand = static_cast<uint32_t>(reg.ToOperand());
     168             :   BytecodeNode node(BytecodeNode::Star(BytecodeSourceInfo(), operand));
     169    20391755 :   Write(&node);
     170    20391098 : }
     171             : 
     172     1378163 : void BytecodeArrayBuilder::OutputMovRaw(Register src, Register dest) {
     173     1378163 :   uint32_t operand0 = static_cast<uint32_t>(src.ToOperand());
     174     1378163 :   uint32_t operand1 = static_cast<uint32_t>(dest.ToOperand());
     175             :   BytecodeNode node(
     176             :       BytecodeNode::Mov(BytecodeSourceInfo(), operand0, operand1));
     177     1378163 :   Write(&node);
     178     1378163 : }
     179             : 
     180             : namespace {
     181             : 
     182             : template <OperandTypeInfo type_info>
     183             : class UnsignedOperandHelper {
     184             :  public:
     185             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     186             :                                     size_t value) {
     187             :     DCHECK(IsValid(value));
     188    38191527 :     return static_cast<uint32_t>(value);
     189             :   }
     190             : 
     191             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder, int value) {
     192             :     DCHECK_GE(value, 0);
     193    32999508 :     return Convert(builder, static_cast<size_t>(value));
     194             :   }
     195             : 
     196             :  private:
     197             :   static bool IsValid(size_t value) {
     198             :     switch (type_info) {
     199             :       case OperandTypeInfo::kFixedUnsignedByte:
     200             :         return value <= kMaxUInt8;
     201             :       case OperandTypeInfo::kFixedUnsignedShort:
     202             :         return value <= kMaxUInt16;
     203             :       case OperandTypeInfo::kScalableUnsignedByte:
     204             :         return value <= kMaxUInt32;
     205             :       default:
     206             :         UNREACHABLE();
     207             :     }
     208             :   }
     209             : };
     210             : 
     211             : template <OperandType>
     212             : class OperandHelper {};
     213             : 
     214             : #define DEFINE_UNSIGNED_OPERAND_HELPER(Name, Type) \
     215             :   template <>                                      \
     216             :   class OperandHelper<OperandType::k##Name>        \
     217             :       : public UnsignedOperandHelper<Type> {};
     218             : UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER)
     219             : UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER)
     220             : #undef DEFINE_UNSIGNED_OPERAND_HELPER
     221             : 
     222             : template <>
     223             : class OperandHelper<OperandType::kImm> {
     224             :  public:
     225             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder, int value) {
     226     6826007 :     return static_cast<uint32_t>(value);
     227             :   }
     228             : };
     229             : 
     230             : template <>
     231             : class OperandHelper<OperandType::kReg> {
     232             :  public:
     233             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     234             :                                     Register reg) {
     235             :     return builder->GetInputRegisterOperand(reg);
     236             :   }
     237             : };
     238             : 
     239             : template <>
     240             : class OperandHelper<OperandType::kRegList> {
     241             :  public:
     242             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     243             :                                     RegisterList reg_list) {
     244     2886670 :     return builder->GetInputRegisterListOperand(reg_list);
     245             :   }
     246             : };
     247             : 
     248             : template <>
     249             : class OperandHelper<OperandType::kRegPair> {
     250             :  public:
     251             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     252             :                                     RegisterList reg_list) {
     253             :     DCHECK_EQ(reg_list.register_count(), 2);
     254        4754 :     return builder->GetInputRegisterListOperand(reg_list);
     255             :   }
     256             : };
     257             : 
     258             : template <>
     259             : class OperandHelper<OperandType::kRegOut> {
     260             :  public:
     261             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     262             :                                     Register reg) {
     263             :     return builder->GetOutputRegisterOperand(reg);
     264             :   }
     265             : };
     266             : 
     267             : template <>
     268             : class OperandHelper<OperandType::kRegOutList> {
     269             :  public:
     270             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     271             :                                     RegisterList reg_list) {
     272             :     return builder->GetOutputRegisterListOperand(reg_list);
     273             :   }
     274             : };
     275             : 
     276             : template <>
     277             : class OperandHelper<OperandType::kRegOutPair> {
     278             :  public:
     279             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     280             :                                     RegisterList reg_list) {
     281             :     DCHECK_EQ(2, reg_list.register_count());
     282             :     return builder->GetOutputRegisterListOperand(reg_list);
     283             :   }
     284             : };
     285             : 
     286             : template <>
     287             : class OperandHelper<OperandType::kRegOutTriple> {
     288             :  public:
     289             :   V8_INLINE static uint32_t Convert(BytecodeArrayBuilder* builder,
     290             :                                     RegisterList reg_list) {
     291             :     DCHECK_EQ(3, reg_list.register_count());
     292             :     return builder->GetOutputRegisterListOperand(reg_list);
     293             :   }
     294             : };
     295             : 
     296             : }  // namespace
     297             : 
     298             : template <Bytecode bytecode, AccumulatorUse accumulator_use,
     299             :           OperandType... operand_types>
     300             : class BytecodeNodeBuilder {
     301             :  public:
     302             :   template <typename... Operands>
     303             :   V8_INLINE static BytecodeNode Make(BytecodeArrayBuilder* builder,
     304             :                                      Operands... operands) {
     305             :     static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands,
     306             :                   "too many operands for bytecode");
     307    53193863 :     builder->PrepareToOutputBytecode<bytecode, accumulator_use>();
     308             :     // The "OperandHelper<operand_types>::Convert(builder, operands)..." will
     309             :     // expand both the OperandType... and Operands... parameter packs e.g. for:
     310             :     //   BytecodeNodeBuilder<OperandType::kReg, OperandType::kImm>::Make<
     311             :     //       Register, int>(..., Register reg, int immediate)
     312             :     // the code will expand into:
     313             :     //    OperandHelper<OperandType::kReg>::Convert(builder, reg),
     314             :     //    OperandHelper<OperandType::kImm>::Convert(builder, immediate),
     315             :     return BytecodeNode::Create<bytecode, accumulator_use, operand_types...>(
     316             :         builder->CurrentSourcePosition(bytecode),
     317             :         OperandHelper<operand_types>::Convert(builder, operands)...);
     318             :   }
     319             : };
     320             : 
     321             : #define DEFINE_BYTECODE_OUTPUT(name, ...)                             \
     322             :   template <typename... Operands>                                     \
     323             :   BytecodeNode BytecodeArrayBuilder::Create##name##Node(              \
     324             :       Operands... operands) {                                         \
     325             :     return BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make( \
     326             :         this, operands...);                                           \
     327             :   }                                                                   \
     328             :                                                                       \
     329             :   template <typename... Operands>                                     \
     330             :   void BytecodeArrayBuilder::Output##name(Operands... operands) {     \
     331             :     BytecodeNode node(Create##name##Node(operands...));               \
     332             :     Write(&node);                                                     \
     333             :   }                                                                   \
     334             :                                                                       \
     335             :   template <typename... Operands>                                     \
     336             :   void BytecodeArrayBuilder::Output##name(BytecodeLabel* label,       \
     337             :                                           Operands... operands) {     \
     338             :     DCHECK(Bytecodes::IsForwardJump(Bytecode::k##name));              \
     339             :     BytecodeNode node(Create##name##Node(operands...));               \
     340             :     WriteJump(&node, label);                                          \
     341             :   }
     342    54433889 : BYTECODE_LIST(DEFINE_BYTECODE_OUTPUT)
     343             : #undef DEFINE_BYTECODE_OUTPUT
     344             : 
     345             : void BytecodeArrayBuilder::OutputJumpLoop(BytecodeLoopHeader* loop_header,
     346             :                                           int loop_depth) {
     347             :   BytecodeNode node(CreateJumpLoopNode(0, loop_depth));
     348      262330 :   WriteJumpLoop(&node, loop_header);
     349             : }
     350             : 
     351             : void BytecodeArrayBuilder::OutputSwitchOnSmiNoFeedback(
     352             :     BytecodeJumpTable* jump_table) {
     353             :   BytecodeNode node(CreateSwitchOnSmiNoFeedbackNode(
     354             :       jump_table->constant_pool_index(), jump_table->size(),
     355             :       jump_table->case_value_base()));
     356       10809 :   WriteSwitch(&node, jump_table);
     357             : }
     358             : 
     359      662182 : BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
     360             :                                                             Register reg,
     361             :                                                             int feedback_slot) {
     362      662182 :   switch (op) {
     363             :     case Token::Value::ADD:
     364             :       OutputAdd(reg, feedback_slot);
     365             :       break;
     366             :     case Token::Value::SUB:
     367             :       OutputSub(reg, feedback_slot);
     368             :       break;
     369             :     case Token::Value::MUL:
     370             :       OutputMul(reg, feedback_slot);
     371             :       break;
     372             :     case Token::Value::DIV:
     373             :       OutputDiv(reg, feedback_slot);
     374             :       break;
     375             :     case Token::Value::MOD:
     376             :       OutputMod(reg, feedback_slot);
     377             :       break;
     378             :     case Token::Value::EXP:
     379             :       OutputExp(reg, feedback_slot);
     380             :       break;
     381             :     case Token::Value::BIT_OR:
     382             :       OutputBitwiseOr(reg, feedback_slot);
     383             :       break;
     384             :     case Token::Value::BIT_XOR:
     385             :       OutputBitwiseXor(reg, feedback_slot);
     386             :       break;
     387             :     case Token::Value::BIT_AND:
     388             :       OutputBitwiseAnd(reg, feedback_slot);
     389             :       break;
     390             :     case Token::Value::SHL:
     391             :       OutputShiftLeft(reg, feedback_slot);
     392             :       break;
     393             :     case Token::Value::SAR:
     394             :       OutputShiftRight(reg, feedback_slot);
     395             :       break;
     396             :     case Token::Value::SHR:
     397             :       OutputShiftRightLogical(reg, feedback_slot);
     398             :       break;
     399             :     default:
     400           0 :       UNREACHABLE();
     401             :   }
     402      662187 :   return *this;
     403             : }
     404             : 
     405      194635 : BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperationSmiLiteral(
     406             :     Token::Value op, Smi literal, int feedback_slot) {
     407      194635 :   switch (op) {
     408             :     case Token::Value::ADD:
     409             :       OutputAddSmi(literal->value(), feedback_slot);
     410             :       break;
     411             :     case Token::Value::SUB:
     412             :       OutputSubSmi(literal->value(), feedback_slot);
     413             :       break;
     414             :     case Token::Value::MUL:
     415             :       OutputMulSmi(literal->value(), feedback_slot);
     416             :       break;
     417             :     case Token::Value::DIV:
     418             :       OutputDivSmi(literal->value(), feedback_slot);
     419             :       break;
     420             :     case Token::Value::MOD:
     421             :       OutputModSmi(literal->value(), feedback_slot);
     422             :       break;
     423             :     case Token::Value::EXP:
     424             :       OutputExpSmi(literal->value(), feedback_slot);
     425             :       break;
     426             :     case Token::Value::BIT_OR:
     427             :       OutputBitwiseOrSmi(literal->value(), feedback_slot);
     428             :       break;
     429             :     case Token::Value::BIT_XOR:
     430             :       OutputBitwiseXorSmi(literal->value(), feedback_slot);
     431             :       break;
     432             :     case Token::Value::BIT_AND:
     433             :       OutputBitwiseAndSmi(literal->value(), feedback_slot);
     434             :       break;
     435             :     case Token::Value::SHL:
     436             :       OutputShiftLeftSmi(literal->value(), feedback_slot);
     437             :       break;
     438             :     case Token::Value::SAR:
     439             :       OutputShiftRightSmi(literal->value(), feedback_slot);
     440             :       break;
     441             :     case Token::Value::SHR:
     442             :       OutputShiftRightLogicalSmi(literal->value(), feedback_slot);
     443             :       break;
     444             :     default:
     445           0 :       UNREACHABLE();
     446             :   }
     447      194634 :   return *this;
     448             : }
     449             : 
     450      312791 : BytecodeArrayBuilder& BytecodeArrayBuilder::UnaryOperation(Token::Value op,
     451             :                                                            int feedback_slot) {
     452      312791 :   switch (op) {
     453             :     case Token::Value::INC:
     454             :       OutputInc(feedback_slot);
     455             :       break;
     456             :     case Token::Value::DEC:
     457             :       OutputDec(feedback_slot);
     458             :       break;
     459             :     case Token::Value::ADD:
     460             :       OutputToNumber(feedback_slot);
     461             :       break;
     462             :     case Token::Value::SUB:
     463             :       OutputNegate(feedback_slot);
     464             :       break;
     465             :     case Token::Value::BIT_NOT:
     466             :       OutputBitwiseNot(feedback_slot);
     467             :       break;
     468             :     default:
     469           0 :       UNREACHABLE();
     470             :   }
     471      312797 :   return *this;
     472             : }
     473             : 
     474       30004 : BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot(ToBooleanMode mode) {
     475       30004 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
     476             :     OutputLogicalNot();
     477             :   } else {
     478             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
     479             :     OutputToBooleanLogicalNot();
     480             :   }
     481       30006 :   return *this;
     482             : }
     483             : 
     484       63811 : BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
     485             :   OutputTypeOf();
     486       63811 :   return *this;
     487             : }
     488             : 
     489        4171 : BytecodeArrayBuilder& BytecodeArrayBuilder::GetSuperConstructor(Register out) {
     490             :   OutputGetSuperConstructor(out);
     491        4171 :   return *this;
     492             : }
     493             : 
     494      812151 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
     495             :     Token::Value op, Register reg, int feedback_slot) {
     496      812151 :   switch (op) {
     497             :     case Token::Value::EQ:
     498             :       OutputTestEqual(reg, feedback_slot);
     499             :       break;
     500             :     case Token::Value::EQ_STRICT:
     501             :       OutputTestEqualStrict(reg, feedback_slot);
     502             :       break;
     503             :     case Token::Value::LT:
     504             :       OutputTestLessThan(reg, feedback_slot);
     505             :       break;
     506             :     case Token::Value::GT:
     507             :       OutputTestGreaterThan(reg, feedback_slot);
     508             :       break;
     509             :     case Token::Value::LTE:
     510             :       OutputTestLessThanOrEqual(reg, feedback_slot);
     511             :       break;
     512             :     case Token::Value::GTE:
     513             :       OutputTestGreaterThanOrEqual(reg, feedback_slot);
     514             :       break;
     515             :     case Token::Value::INSTANCEOF:
     516             :       OutputTestInstanceOf(reg, feedback_slot);
     517             :       break;
     518             :     case Token::Value::IN:
     519             :       OutputTestIn(reg, feedback_slot);
     520             :       break;
     521             :     default:
     522           0 :       UNREACHABLE();
     523             :   }
     524      812156 :   return *this;
     525             : }
     526             : 
     527       93071 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareReference(Register reg) {
     528             :   OutputTestReferenceEqual(reg);
     529       93075 :   return *this;
     530             : }
     531             : 
     532        3085 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareUndetectable() {
     533             :   OutputTestUndetectable();
     534        3085 :   return *this;
     535             : }
     536             : 
     537        9280 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareUndefined() {
     538             :   OutputTestUndefined();
     539        9280 :   return *this;
     540             : }
     541             : 
     542        1019 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareNull() {
     543             :   OutputTestNull();
     544        1019 :   return *this;
     545             : }
     546             : 
     547       12180 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareNil(Token::Value op,
     548             :                                                        NilValue nil) {
     549       12180 :   if (op == Token::EQ) {
     550        1883 :     return CompareUndetectable();
     551             :   } else {
     552             :     DCHECK_EQ(Token::EQ_STRICT, op);
     553       10297 :     if (nil == kUndefinedValue) {
     554        9279 :       return CompareUndefined();
     555             :     } else {
     556             :       DCHECK_EQ(kNullValue, nil);
     557        1018 :       return CompareNull();
     558             :     }
     559             :   }
     560             : }
     561             : 
     562      138046 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareTypeOf(
     563             :     TestTypeOfFlags::LiteralFlag literal_flag) {
     564             :   DCHECK_NE(literal_flag, TestTypeOfFlags::LiteralFlag::kOther);
     565      138046 :   OutputTestTypeOf(TestTypeOfFlags::Encode(literal_flag));
     566      138047 :   return *this;
     567             : }
     568             : 
     569      488533 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry(
     570             :     size_t entry) {
     571             :   OutputLdaConstant(entry);
     572      488559 :   return *this;
     573             : }
     574             : 
     575     8090916 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Smi smi) {
     576             :   int32_t raw_smi = smi->value();
     577     8090916 :   if (raw_smi == 0) {
     578             :     OutputLdaZero();
     579             :   } else {
     580             :     OutputLdaSmi(raw_smi);
     581             :   }
     582     8090935 :   return *this;
     583             : }
     584             : 
     585      612370 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(double value) {
     586             :   size_t entry = GetConstantPoolEntry(value);
     587             :   OutputLdaConstant(entry);
     588      612371 :   return *this;
     589             : }
     590             : 
     591     2017691 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
     592             :     const AstRawString* raw_string) {
     593             :   size_t entry = GetConstantPoolEntry(raw_string);
     594             :   OutputLdaConstant(entry);
     595     2017694 :   return *this;
     596             : }
     597             : 
     598       13387 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(const Scope* scope) {
     599             :   size_t entry = GetConstantPoolEntry(scope);
     600             :   OutputLdaConstant(entry);
     601       13387 :   return *this;
     602             : }
     603             : 
     604       10475 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(AstBigInt bigint) {
     605             :   size_t entry = GetConstantPoolEntry(bigint);
     606             :   OutputLdaConstant(entry);
     607       10478 :   return *this;
     608             : }
     609             : 
     610        1991 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(AstSymbol symbol) {
     611             :   size_t entry;
     612        1991 :   switch (symbol) {
     613             :     case AstSymbol::kHomeObjectSymbol:
     614             :       entry = HomeObjectSymbolConstantPoolEntry();
     615        1991 :       break;
     616             :       // No default case so that we get a warning if AstSymbol changes
     617             :   }
     618             :   OutputLdaConstant(entry);
     619        1991 :   return *this;
     620             : }
     621             : 
     622     1509500 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() {
     623             :   OutputLdaUndefined();
     624     1509574 :   return *this;
     625             : }
     626             : 
     627       27078 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() {
     628             :   OutputLdaNull();
     629       27078 :   return *this;
     630             : }
     631             : 
     632      924818 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
     633             :   OutputLdaTheHole();
     634      924823 :   return *this;
     635             : }
     636             : 
     637      166974 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
     638             :   OutputLdaTrue();
     639      166980 :   return *this;
     640             : }
     641             : 
     642      289213 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
     643             :   OutputLdaFalse();
     644      289225 :   return *this;
     645             : }
     646             : 
     647      332816 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBoolean(bool value) {
     648      332816 :   return value ? LoadTrue() : LoadFalse();
     649             : }
     650             : 
     651     7821018 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
     652             :     Register reg) {
     653     7821018 :   if (register_optimizer_) {
     654             :     // Defer source info so that if we elide the bytecode transfer, we attach
     655             :     // the source info to a subsequent bytecode if it exists.
     656             :     SetDeferredSourceInfo(CurrentSourcePosition(Bytecode::kLdar));
     657             :     register_optimizer_->DoLdar(reg);
     658             :   } else {
     659             :     OutputLdar(reg);
     660             :   }
     661     7821052 :   return *this;
     662             : }
     663             : 
     664    25490448 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
     665             :     Register reg) {
     666    25490448 :   if (register_optimizer_) {
     667             :     // Defer source info so that if we elide the bytecode transfer, we attach
     668             :     // the source info to a subsequent bytecode if it exists.
     669             :     SetDeferredSourceInfo(CurrentSourcePosition(Bytecode::kStar));
     670             :     register_optimizer_->DoStar(reg);
     671             :   } else {
     672             :     OutputStar(reg);
     673             :   }
     674    25491027 :   return *this;
     675             : }
     676             : 
     677      735552 : BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
     678             :                                                          Register to) {
     679             :   DCHECK(from != to);
     680      735552 :   if (register_optimizer_) {
     681             :     // Defer source info so that if we elide the bytecode transfer, we attach
     682             :     // the source info to a subsequent bytecode if it exists.
     683             :     SetDeferredSourceInfo(CurrentSourcePosition(Bytecode::kMov));
     684      735222 :     register_optimizer_->DoMov(from, to);
     685             :   } else {
     686             :     OutputMov(from, to);
     687             :   }
     688      735571 :   return *this;
     689             : }
     690             : 
     691     5819321 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(const AstRawString* name,
     692             :                                                        int feedback_slot,
     693             :                                                        TypeofMode typeof_mode) {
     694             :   size_t name_index = GetConstantPoolEntry(name);
     695             :   // Ensure that typeof mode is in sync with the IC slot kind.
     696             :   DCHECK_EQ(GetTypeofModeFromSlotKind(feedback_vector_spec()->GetKind(
     697             :                 FeedbackVector::ToSlot(feedback_slot))),
     698             :             typeof_mode);
     699     5819281 :   if (typeof_mode == INSIDE_TYPEOF) {
     700             :     OutputLdaGlobalInsideTypeof(name_index, feedback_slot);
     701             :   } else {
     702             :     DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF);
     703             :     OutputLdaGlobal(name_index, feedback_slot);
     704             :   }
     705     5819281 :   return *this;
     706             : }
     707             : 
     708     1465434 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
     709             :     const AstRawString* name, int feedback_slot) {
     710             :   size_t name_index = GetConstantPoolEntry(name);
     711             :   OutputStaGlobal(name_index, feedback_slot);
     712     1465449 :   return *this;
     713             : }
     714             : 
     715     1079704 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(
     716             :     Register context, int slot_index, int depth,
     717             :     ContextSlotMutability mutability) {
     718     1079704 :   if (context.is_current_context() && depth == 0) {
     719      972245 :     if (mutability == kImmutableSlot) {
     720             :       OutputLdaImmutableCurrentContextSlot(slot_index);
     721             :     } else {
     722             :       DCHECK_EQ(kMutableSlot, mutability);
     723             :       OutputLdaCurrentContextSlot(slot_index);
     724             :     }
     725      107463 :   } else if (mutability == kImmutableSlot) {
     726             :     OutputLdaImmutableContextSlot(context, slot_index, depth);
     727             :   } else {
     728             :     DCHECK_EQ(mutability, kMutableSlot);
     729             :     OutputLdaContextSlot(context, slot_index, depth);
     730             :   }
     731     1079708 :   return *this;
     732             : }
     733             : 
     734     2892386 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
     735             :                                                              int slot_index,
     736             :                                                              int depth) {
     737     2892386 :   if (context.is_current_context() && depth == 0) {
     738             :     OutputStaCurrentContextSlot(slot_index);
     739             :   } else {
     740             :     OutputStaContextSlot(context, slot_index, depth);
     741             :   }
     742     2892329 :   return *this;
     743             : }
     744             : 
     745       25926 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
     746             :     const AstRawString* name, TypeofMode typeof_mode) {
     747             :   size_t name_index = GetConstantPoolEntry(name);
     748       25926 :   if (typeof_mode == INSIDE_TYPEOF) {
     749             :     OutputLdaLookupSlotInsideTypeof(name_index);
     750             :   } else {
     751             :     DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF);
     752             :     OutputLdaLookupSlot(name_index);
     753             :   }
     754       25926 :   return *this;
     755             : }
     756             : 
     757        3462 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot(
     758             :     const AstRawString* name, TypeofMode typeof_mode, int slot_index,
     759             :     int depth) {
     760             :   size_t name_index = GetConstantPoolEntry(name);
     761        3462 :   if (typeof_mode == INSIDE_TYPEOF) {
     762             :     OutputLdaLookupContextSlotInsideTypeof(name_index, slot_index, depth);
     763             :   } else {
     764             :     DCHECK(typeof_mode == NOT_INSIDE_TYPEOF);
     765             :     OutputLdaLookupContextSlot(name_index, slot_index, depth);
     766             :   }
     767        3462 :   return *this;
     768             : }
     769             : 
     770      355516 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot(
     771             :     const AstRawString* name, TypeofMode typeof_mode, int feedback_slot,
     772             :     int depth) {
     773             :   size_t name_index = GetConstantPoolEntry(name);
     774      355516 :   if (typeof_mode == INSIDE_TYPEOF) {
     775             :     OutputLdaLookupGlobalSlotInsideTypeof(name_index, feedback_slot, depth);
     776             :   } else {
     777             :     DCHECK(typeof_mode == NOT_INSIDE_TYPEOF);
     778             :     OutputLdaLookupGlobalSlot(name_index, feedback_slot, depth);
     779             :   }
     780      355516 :   return *this;
     781             : }
     782             : 
     783       37378 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
     784             :     const AstRawString* name, LanguageMode language_mode,
     785             :     LookupHoistingMode lookup_hoisting_mode) {
     786             :   size_t name_index = GetConstantPoolEntry(name);
     787             :   uint8_t flags =
     788       37378 :       StoreLookupSlotFlags::Encode(language_mode, lookup_hoisting_mode);
     789             :   OutputStaLookupSlot(name_index, flags);
     790       37378 :   return *this;
     791             : }
     792             : 
     793     1352922 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
     794             :     Register object, const AstRawString* name, int feedback_slot) {
     795             :   size_t name_index = GetConstantPoolEntry(name);
     796             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     797     1352915 :   return *this;
     798             : }
     799             : 
     800     1279929 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedPropertyNoFeedback(
     801             :     Register object, const AstRawString* name) {
     802             :   size_t name_index = GetConstantPoolEntry(name);
     803             :   OutputLdaNamedPropertyNoFeedback(object, name_index);
     804     1279935 :   return *this;
     805             : }
     806             : 
     807      142642 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
     808             :     Register object, int feedback_slot) {
     809             :   OutputLdaKeyedProperty(object, feedback_slot);
     810      142642 :   return *this;
     811             : }
     812             : 
     813       39866 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadIteratorProperty(
     814             :     Register object, int feedback_slot) {
     815             :   size_t name_index = IteratorSymbolConstantPoolEntry();
     816             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     817       39869 :   return *this;
     818             : }
     819             : 
     820         351 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAsyncIteratorProperty(
     821             :     Register object, int feedback_slot) {
     822             :   size_t name_index = AsyncIteratorSymbolConstantPoolEntry();
     823             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     824         351 :   return *this;
     825             : }
     826             : 
     827        2400 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
     828             :     Register object, Register name, DataPropertyInLiteralFlags flags,
     829             :     int feedback_slot) {
     830             :   OutputStaDataPropertyInLiteral(object, name, flags, feedback_slot);
     831        2400 :   return *this;
     832             : }
     833             : 
     834         164 : BytecodeArrayBuilder& BytecodeArrayBuilder::CollectTypeProfile(int position) {
     835             :   OutputCollectTypeProfile(position);
     836         164 :   return *this;
     837             : }
     838             : 
     839     2294333 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
     840             :     Register object, size_t name_index, int feedback_slot,
     841             :     LanguageMode language_mode) {
     842             :   // Ensure that language mode is in sync with the IC slot kind.
     843             :   DCHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(
     844             :                 FeedbackVector::ToSlot(feedback_slot))),
     845             :             language_mode);
     846             :   OutputStaNamedProperty(object, name_index, feedback_slot);
     847     2294334 :   return *this;
     848             : }
     849             : 
     850     2292594 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
     851             :     Register object, const AstRawString* name, int feedback_slot,
     852             :     LanguageMode language_mode) {
     853             :   size_t name_index = GetConstantPoolEntry(name);
     854     2292596 :   return StoreNamedProperty(object, name_index, feedback_slot, language_mode);
     855             : }
     856             : 
     857      115023 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedPropertyNoFeedback(
     858             :     Register object, const AstRawString* name, LanguageMode language_mode) {
     859             :   size_t name_index = GetConstantPoolEntry(name);
     860             :   OutputStaNamedPropertyNoFeedback(object, name_index,
     861             :                                    static_cast<uint8_t>(language_mode));
     862      115039 :   return *this;
     863             : }
     864             : 
     865      244108 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedOwnProperty(
     866             :     Register object, const AstRawString* name, int feedback_slot) {
     867             :   size_t name_index = GetConstantPoolEntry(name);
     868             :   // Ensure that the store operation is in sync with the IC slot kind.
     869             :   DCHECK_EQ(
     870             :       FeedbackSlotKind::kStoreOwnNamed,
     871             :       feedback_vector_spec()->GetKind(FeedbackVector::ToSlot(feedback_slot)));
     872             :   OutputStaNamedOwnProperty(object, name_index, feedback_slot);
     873      244113 :   return *this;
     874             : }
     875             : 
     876       36527 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
     877             :     Register object, Register key, int feedback_slot,
     878             :     LanguageMode language_mode) {
     879             :   // Ensure that language mode is in sync with the IC slot kind.
     880             :   DCHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(
     881             :                 FeedbackVector::ToSlot(feedback_slot))),
     882             :             language_mode);
     883             :   OutputStaKeyedProperty(object, key, feedback_slot);
     884       36530 :   return *this;
     885             : }
     886             : 
     887      261446 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreInArrayLiteral(
     888             :     Register array, Register index, int feedback_slot) {
     889             :   OutputStaInArrayLiteral(array, index, feedback_slot);
     890      261448 :   return *this;
     891             : }
     892             : 
     893         706 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreHomeObjectProperty(
     894             :     Register object, int feedback_slot, LanguageMode language_mode) {
     895             :   size_t name_index = HomeObjectSymbolConstantPoolEntry();
     896         706 :   return StoreNamedProperty(object, name_index, feedback_slot, language_mode);
     897             : }
     898             : 
     899        1032 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreClassFieldsInitializer(
     900             :     Register constructor, int feedback_slot) {
     901             :   size_t name_index = ClassFieldsSymbolConstantPoolEntry();
     902             :   return StoreNamedProperty(constructor, name_index, feedback_slot,
     903        1032 :                             LanguageMode::kStrict);
     904             : }
     905             : 
     906         941 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadClassFieldsInitializer(
     907             :     Register constructor, int feedback_slot) {
     908             :   size_t name_index = ClassFieldsSymbolConstantPoolEntry();
     909             :   OutputLdaNamedProperty(constructor, name_index, feedback_slot);
     910         941 :   return *this;
     911             : }
     912             : 
     913     2710012 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
     914             :     size_t shared_function_info_entry, int slot, int flags) {
     915             :   OutputCreateClosure(shared_function_info_entry, slot, flags);
     916     2710029 :   return *this;
     917             : }
     918             : 
     919       59768 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateBlockContext(
     920             :     const Scope* scope) {
     921             :   size_t entry = GetConstantPoolEntry(scope);
     922             :   OutputCreateBlockContext(entry);
     923       59769 :   return *this;
     924             : }
     925             : 
     926       74707 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateCatchContext(
     927             :     Register exception, const Scope* scope) {
     928             :   size_t scope_index = GetConstantPoolEntry(scope);
     929             :   OutputCreateCatchContext(exception, scope_index);
     930       74711 :   return *this;
     931             : }
     932             : 
     933      135584 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(
     934             :     const Scope* scope, int slots) {
     935             :   size_t scope_index = GetConstantPoolEntry(scope);
     936             :   OutputCreateFunctionContext(scope_index, slots);
     937      135584 :   return *this;
     938             : }
     939             : 
     940       42312 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEvalContext(
     941             :     const Scope* scope, int slots) {
     942             :   size_t scope_index = GetConstantPoolEntry(scope);
     943             :   OutputCreateEvalContext(scope_index, slots);
     944       42312 :   return *this;
     945             : }
     946             : 
     947        2964 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(
     948             :     Register object, const Scope* scope) {
     949             :   size_t scope_index = GetConstantPoolEntry(scope);
     950             :   OutputCreateWithContext(object, scope_index);
     951        2964 :   return *this;
     952             : }
     953             : 
     954      105421 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
     955             :     CreateArgumentsType type) {
     956      105421 :   switch (type) {
     957             :     case CreateArgumentsType::kMappedArguments:
     958             :       OutputCreateMappedArguments();
     959             :       break;
     960             :     case CreateArgumentsType::kUnmappedArguments:
     961             :       OutputCreateUnmappedArguments();
     962             :       break;
     963             :     case CreateArgumentsType::kRestParameter:
     964             :       OutputCreateRestParameter();
     965             :       break;
     966             :     default:
     967           0 :       UNREACHABLE();
     968             :   }
     969      105421 :   return *this;
     970             : }
     971             : 
     972       45109 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
     973             :     const AstRawString* pattern, int literal_index, int flags) {
     974             :   size_t pattern_entry = GetConstantPoolEntry(pattern);
     975             :   OutputCreateRegExpLiteral(pattern_entry, literal_index, flags);
     976       45111 :   return *this;
     977             : }
     978             : 
     979      139845 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyArrayLiteral(
     980             :     int literal_index) {
     981             :   OutputCreateEmptyArrayLiteral(literal_index);
     982      139847 :   return *this;
     983             : }
     984             : 
     985       30498 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
     986             :     size_t constant_elements_entry, int literal_index, int flags) {
     987             :   OutputCreateArrayLiteral(constant_elements_entry, literal_index, flags);
     988       30500 :   return *this;
     989             : }
     990             : 
     991        2071 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayFromIterable() {
     992             :   OutputCreateArrayFromIterable();
     993        2072 :   return *this;
     994             : }
     995             : 
     996       87972 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
     997             :     size_t constant_properties_entry, int literal_index, int flags) {
     998             :   OutputCreateObjectLiteral(constant_properties_entry, literal_index, flags);
     999       87977 :   return *this;
    1000             : }
    1001             : 
    1002       28241 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyObjectLiteral() {
    1003             :   OutputCreateEmptyObjectLiteral();
    1004       28242 :   return *this;
    1005             : }
    1006             : 
    1007         285 : BytecodeArrayBuilder& BytecodeArrayBuilder::CloneObject(Register source,
    1008             :                                                         int flags,
    1009             :                                                         int feedback_slot) {
    1010             :   OutputCloneObject(source, flags, feedback_slot);
    1011         285 :   return *this;
    1012             : }
    1013             : 
    1014        1931 : BytecodeArrayBuilder& BytecodeArrayBuilder::GetTemplateObject(
    1015             :     size_t template_object_description_entry, int feedback_slot) {
    1016             :   OutputGetTemplateObject(template_object_description_entry, feedback_slot);
    1017        1931 :   return *this;
    1018             : }
    1019             : 
    1020      328719 : BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
    1021             :   OutputPushContext(context);
    1022      328721 :   return *this;
    1023             : }
    1024             : 
    1025      338140 : BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
    1026             :   OutputPopContext(context);
    1027      338141 :   return *this;
    1028             : }
    1029             : 
    1030        8000 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToObject(Register out) {
    1031             :   OutputToObject(out);
    1032        8000 :   return *this;
    1033             : }
    1034             : 
    1035        8092 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToName(Register out) {
    1036             :   OutputToName(out);
    1037        8092 :   return *this;
    1038             : }
    1039             : 
    1040       10472 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToString() {
    1041             :   OutputToString();
    1042       10473 :   return *this;
    1043             : }
    1044             : 
    1045           1 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToNumber(int feedback_slot) {
    1046             :   OutputToNumber(feedback_slot);
    1047           1 :   return *this;
    1048             : }
    1049             : 
    1050       30575 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToNumeric(int feedback_slot) {
    1051             :   OutputToNumeric(feedback_slot);
    1052       30576 :   return *this;
    1053             : }
    1054             : 
    1055     1879462 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
    1056             :   // Don't generate code for a label which hasn't had a corresponding forward
    1057             :   // jump generated already. For backwards jumps, use BindLoopHeader.
    1058     1879462 :   if (!label->has_referrer_jump()) return *this;
    1059             : 
    1060             :   // Flush the register optimizer when binding a label to ensure all
    1061             :   // expected registers are valid when jumping to this label.
    1062     1820849 :   if (register_optimizer_) register_optimizer_->Flush();
    1063     1820857 :   bytecode_array_writer_.BindLabel(label);
    1064     1820847 :   return *this;
    1065             : }
    1066             : 
    1067      262292 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(
    1068             :     BytecodeLoopHeader* loop_header) {
    1069             :   // Flush the register optimizer when starting a loop to ensure all expected
    1070             :   // registers are valid when jumping to the loop header.
    1071      262292 :   if (register_optimizer_) register_optimizer_->Flush();
    1072      262294 :   bytecode_array_writer_.BindLoopHeader(loop_header);
    1073      262294 :   return *this;
    1074             : }
    1075             : 
    1076       46832 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeJumpTable* jump_table,
    1077             :                                                  int case_value) {
    1078             :   // Flush the register optimizer when binding a jump table entry to ensure
    1079             :   // all expected registers are valid when jumping to this location.
    1080       46832 :   if (register_optimizer_) register_optimizer_->Flush();
    1081       46832 :   bytecode_array_writer_.BindJumpTableEntry(jump_table, case_value);
    1082       46832 :   return *this;
    1083             : }
    1084             : 
    1085      154536 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(
    1086             :     int handler_id, HandlerTable::CatchPrediction catch_prediction) {
    1087             :   // The handler starts a new basic block, and any reasonable try block won't
    1088             :   // let control fall through into it.
    1089             :   DCHECK_IMPLIES(register_optimizer_,
    1090             :                  register_optimizer_->EnsureAllRegistersAreFlushed());
    1091      154536 :   bytecode_array_writer_.BindHandlerTarget(handler_table_builder(), handler_id);
    1092      154537 :   handler_table_builder()->SetPrediction(handler_id, catch_prediction);
    1093      154538 :   return *this;
    1094             : }
    1095             : 
    1096      154533 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
    1097             :                                                          Register context) {
    1098             :   // Flush registers to make sure everything visible to the handler is
    1099             :   // materialized.
    1100      154533 :   if (register_optimizer_) register_optimizer_->Flush();
    1101      154537 :   bytecode_array_writer_.BindTryRegionStart(handler_table_builder(),
    1102      154537 :                                             handler_id);
    1103      154538 :   handler_table_builder()->SetContextRegister(handler_id, context);
    1104      154540 :   return *this;
    1105             : }
    1106             : 
    1107      154533 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
    1108      154533 :   bytecode_array_writer_.BindTryRegionEnd(handler_table_builder(), handler_id);
    1109      154537 :   return *this;
    1110             : }
    1111             : 
    1112      308501 : BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
    1113             :   DCHECK(!label->is_bound());
    1114             :   OutputJump(label, 0);
    1115      308504 :   return *this;
    1116             : }
    1117             : 
    1118      553394 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(ToBooleanMode mode,
    1119             :                                                        BytecodeLabel* label) {
    1120             :   DCHECK(!label->is_bound());
    1121      553394 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
    1122             :     OutputJumpIfTrue(label, 0);
    1123             :   } else {
    1124             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
    1125             :     OutputJumpIfToBooleanTrue(label, 0);
    1126             :   }
    1127      553398 :   return *this;
    1128             : }
    1129             : 
    1130      685210 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(ToBooleanMode mode,
    1131             :                                                         BytecodeLabel* label) {
    1132             :   DCHECK(!label->is_bound());
    1133      685210 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
    1134             :     OutputJumpIfFalse(label, 0);
    1135             :   } else {
    1136             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
    1137             :     OutputJumpIfToBooleanFalse(label, 0);
    1138             :   }
    1139      685212 :   return *this;
    1140             : }
    1141             : 
    1142       57311 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
    1143             :   DCHECK(!label->is_bound());
    1144             :   OutputJumpIfNull(label, 0);
    1145       57315 :   return *this;
    1146             : }
    1147             : 
    1148         656 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotNull(
    1149             :     BytecodeLabel* label) {
    1150             :   DCHECK(!label->is_bound());
    1151             :   OutputJumpIfNotNull(label, 0);
    1152         656 :   return *this;
    1153             : }
    1154             : 
    1155       87551 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
    1156             :     BytecodeLabel* label) {
    1157             :   DCHECK(!label->is_bound());
    1158             :   OutputJumpIfUndefined(label, 0);
    1159       87554 :   return *this;
    1160             : }
    1161             : 
    1162       25777 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotUndefined(
    1163             :     BytecodeLabel* label) {
    1164             :   DCHECK(!label->is_bound());
    1165             :   OutputJumpIfNotUndefined(label, 0);
    1166       25778 :   return *this;
    1167             : }
    1168             : 
    1169       39857 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNil(BytecodeLabel* label,
    1170             :                                                       Token::Value op,
    1171             :                                                       NilValue nil) {
    1172       39857 :   if (op == Token::EQ) {
    1173             :     // TODO(rmcilroy): Implement JumpIfUndetectable.
    1174         177 :     return CompareUndetectable().JumpIfTrue(ToBooleanMode::kAlreadyBoolean,
    1175         177 :                                             label);
    1176             :   } else {
    1177             :     DCHECK_EQ(Token::EQ_STRICT, op);
    1178       39680 :     if (nil == kUndefinedValue) {
    1179       37703 :       return JumpIfUndefined(label);
    1180             :     } else {
    1181             :       DCHECK_EQ(kNullValue, nil);
    1182        1977 :       return JumpIfNull(label);
    1183             :     }
    1184             :   }
    1185             : }
    1186             : 
    1187       14433 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotNil(BytecodeLabel* label,
    1188             :                                                          Token::Value op,
    1189             :                                                          NilValue nil) {
    1190       14433 :   if (op == Token::EQ) {
    1191             :     // TODO(rmcilroy): Implement JumpIfUndetectable.
    1192        1024 :     return CompareUndetectable().JumpIfFalse(ToBooleanMode::kAlreadyBoolean,
    1193        1024 :                                              label);
    1194             :   } else {
    1195             :     DCHECK_EQ(Token::EQ_STRICT, op);
    1196       13409 :     if (nil == kUndefinedValue) {
    1197       12755 :       return JumpIfNotUndefined(label);
    1198             :     } else {
    1199             :       DCHECK_EQ(kNullValue, nil);
    1200         654 :       return JumpIfNotNull(label);
    1201             :     }
    1202             :   }
    1203             : }
    1204             : 
    1205      119521 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfJSReceiver(
    1206             :     BytecodeLabel* label) {
    1207             :   DCHECK(!label->is_bound());
    1208             :   OutputJumpIfJSReceiver(label, 0);
    1209      119526 :   return *this;
    1210             : }
    1211             : 
    1212      262327 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(
    1213             :     BytecodeLoopHeader* loop_header, int loop_depth) {
    1214             :   OutputJumpLoop(loop_header, loop_depth);
    1215      262340 :   return *this;
    1216             : }
    1217             : 
    1218       10809 : BytecodeArrayBuilder& BytecodeArrayBuilder::SwitchOnSmiNoFeedback(
    1219             :     BytecodeJumpTable* jump_table) {
    1220             :   OutputSwitchOnSmiNoFeedback(jump_table);
    1221       10809 :   return *this;
    1222             : }
    1223             : 
    1224     2376659 : BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
    1225     2376659 :   if (position != kNoSourcePosition) {
    1226             :     // We need to attach a non-breakable source position to a stack
    1227             :     // check, so we simply add it as expression position. There can be
    1228             :     // a prior statement position from constructs like:
    1229             :     //
    1230             :     //    do var x;  while (false);
    1231             :     //
    1232             :     // A Nop could be inserted for empty statements, but since no code
    1233             :     // is associated with these positions, instead we force the stack
    1234             :     // check's expression position which eliminates the empty
    1235             :     // statement's position.
    1236             :     latest_source_info_.ForceExpressionPosition(position);
    1237             :   }
    1238             :   OutputStackCheck();
    1239     2376681 :   return *this;
    1240             : }
    1241             : 
    1242      157904 : BytecodeArrayBuilder& BytecodeArrayBuilder::SetPendingMessage() {
    1243             :   OutputSetPendingMessage();
    1244      157904 :   return *this;
    1245             : }
    1246             : 
    1247       67013 : BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
    1248             :   OutputThrow();
    1249       67015 :   return *this;
    1250             : }
    1251             : 
    1252       88814 : BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
    1253             :   OutputReThrow();
    1254       88820 :   return *this;
    1255             : }
    1256             : 
    1257           1 : BytecodeArrayBuilder& BytecodeArrayBuilder::Abort(AbortReason reason) {
    1258             :   DCHECK_LT(reason, AbortReason::kLastErrorMessage);
    1259             :   DCHECK_GE(reason, AbortReason::kNoReason);
    1260             :   OutputAbort(static_cast<int>(reason));
    1261           1 :   return *this;
    1262             : }
    1263             : 
    1264     2481546 : BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
    1265             :   OutputReturn();
    1266     2481644 :   return *this;
    1267             : }
    1268             : 
    1269      309214 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowReferenceErrorIfHole(
    1270             :     const AstRawString* name) {
    1271             :   size_t entry = GetConstantPoolEntry(name);
    1272             :   OutputThrowReferenceErrorIfHole(entry);
    1273      309217 :   return *this;
    1274             : }
    1275             : 
    1276     2170820 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperNotCalledIfHole() {
    1277             :   OutputThrowSuperNotCalledIfHole();
    1278     2170820 :   return *this;
    1279             : }
    1280             : 
    1281        2547 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperAlreadyCalledIfNotHole() {
    1282             :   OutputThrowSuperAlreadyCalledIfNotHole();
    1283        2547 :   return *this;
    1284             : }
    1285             : 
    1286        7592 : BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
    1287             :   OutputDebugger();
    1288        7592 :   return *this;
    1289             : }
    1290             : 
    1291        2033 : BytecodeArrayBuilder& BytecodeArrayBuilder::IncBlockCounter(
    1292             :     int coverage_array_slot) {
    1293             :   OutputIncBlockCounter(coverage_array_slot);
    1294        2033 :   return *this;
    1295             : }
    1296             : 
    1297        4753 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInEnumerate(Register receiver) {
    1298             :   OutputForInEnumerate(receiver);
    1299        4753 :   return *this;
    1300             : }
    1301             : 
    1302        4761 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
    1303             :     RegisterList cache_info_triple, int feedback_slot) {
    1304             :   DCHECK_EQ(3, cache_info_triple.register_count());
    1305             :   OutputForInPrepare(cache_info_triple, feedback_slot);
    1306        4762 :   return *this;
    1307             : }
    1308             : 
    1309        4753 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInContinue(
    1310             :     Register index, Register cache_length) {
    1311             :   OutputForInContinue(index, cache_length);
    1312        4754 :   return *this;
    1313             : }
    1314             : 
    1315        4754 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
    1316             :     Register receiver, Register index, RegisterList cache_type_array_pair,
    1317             :     int feedback_slot) {
    1318             :   DCHECK_EQ(2, cache_type_array_pair.register_count());
    1319             :   OutputForInNext(receiver, index, cache_type_array_pair, feedback_slot);
    1320        4754 :   return *this;
    1321             : }
    1322             : 
    1323        4754 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
    1324             :   OutputForInStep(index);
    1325        4754 :   return *this;
    1326             : }
    1327             : 
    1328       34860 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreModuleVariable(int cell_index,
    1329             :                                                                 int depth) {
    1330             :   OutputStaModuleVariable(cell_index, depth);
    1331       34860 :   return *this;
    1332             : }
    1333             : 
    1334        1432 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadModuleVariable(int cell_index,
    1335             :                                                                int depth) {
    1336             :   OutputLdaModuleVariable(cell_index, depth);
    1337        1432 :   return *this;
    1338             : }
    1339             : 
    1340       23951 : BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
    1341             :     Register generator, RegisterList registers, int suspend_id) {
    1342             :   OutputSuspendGenerator(generator, registers, registers.register_count(),
    1343             :                          suspend_id);
    1344       23951 :   return *this;
    1345             : }
    1346             : 
    1347        9421 : BytecodeArrayBuilder& BytecodeArrayBuilder::SwitchOnGeneratorState(
    1348             :     Register generator, BytecodeJumpTable* jump_table) {
    1349             :   DCHECK_EQ(jump_table->case_value_base(), 0);
    1350             :   BytecodeNode node(CreateSwitchOnGeneratorStateNode(
    1351             :       generator, jump_table->constant_pool_index(), jump_table->size()));
    1352        9421 :   WriteSwitch(&node, jump_table);
    1353        9421 :   return *this;
    1354             : }
    1355             : 
    1356       23951 : BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
    1357             :     Register generator, RegisterList registers) {
    1358             :   OutputResumeGenerator(generator, registers, registers.register_count());
    1359       23951 :   return *this;
    1360             : }
    1361             : 
    1362      633694 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallProperty(Register callable,
    1363             :                                                          RegisterList args,
    1364             :                                                          int feedback_slot) {
    1365      633694 :   if (args.register_count() == 1) {
    1366             :     OutputCallProperty0(callable, args[0], feedback_slot);
    1367      442458 :   } else if (args.register_count() == 2) {
    1368             :     OutputCallProperty1(callable, args[0], args[1], feedback_slot);
    1369      105331 :   } else if (args.register_count() == 3) {
    1370             :     OutputCallProperty2(callable, args[0], args[1], args[2], feedback_slot);
    1371             :   } else {
    1372             :     OutputCallProperty(callable, args, args.register_count(), feedback_slot);
    1373             :   }
    1374      633709 :   return *this;
    1375             : }
    1376             : 
    1377     3412482 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallUndefinedReceiver(
    1378             :     Register callable, RegisterList args, int feedback_slot) {
    1379     3412482 :   if (args.register_count() == 0) {
    1380             :     OutputCallUndefinedReceiver0(callable, feedback_slot);
    1381     1002106 :   } else if (args.register_count() == 1) {
    1382             :     OutputCallUndefinedReceiver1(callable, args[0], feedback_slot);
    1383      607035 :   } else if (args.register_count() == 2) {
    1384             :     OutputCallUndefinedReceiver2(callable, args[0], args[1], feedback_slot);
    1385             :   } else {
    1386             :     OutputCallUndefinedReceiver(callable, args, args.register_count(),
    1387             :                                 feedback_slot);
    1388             :   }
    1389     3412486 :   return *this;
    1390             : }
    1391             : 
    1392        3288 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallAnyReceiver(Register callable,
    1393             :                                                             RegisterList args,
    1394             :                                                             int feedback_slot) {
    1395             :   OutputCallAnyReceiver(callable, args, args.register_count(), feedback_slot);
    1396        3288 :   return *this;
    1397             : }
    1398             : 
    1399     1245109 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallNoFeedback(Register callable,
    1400             :                                                            RegisterList args) {
    1401             :   OutputCallNoFeedback(callable, args, args.register_count());
    1402     1245150 :   return *this;
    1403             : }
    1404             : 
    1405        1696 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallWithSpread(Register callable,
    1406             :                                                            RegisterList args,
    1407             :                                                            int feedback_slot) {
    1408             :   OutputCallWithSpread(callable, args, args.register_count(), feedback_slot);
    1409        1696 :   return *this;
    1410             : }
    1411             : 
    1412      146882 : BytecodeArrayBuilder& BytecodeArrayBuilder::Construct(Register constructor,
    1413             :                                                       RegisterList args,
    1414             :                                                       int feedback_slot_id) {
    1415             :   OutputConstruct(constructor, args, args.register_count(), feedback_slot_id);
    1416      146893 :   return *this;
    1417             : }
    1418             : 
    1419        2981 : BytecodeArrayBuilder& BytecodeArrayBuilder::ConstructWithSpread(
    1420             :     Register constructor, RegisterList args, int feedback_slot_id) {
    1421             :   OutputConstructWithSpread(constructor, args, args.register_count(),
    1422             :                             feedback_slot_id);
    1423        2981 :   return *this;
    1424             : }
    1425             : 
    1426     1245550 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1427             :     Runtime::FunctionId function_id, RegisterList args) {
    1428             :   DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
    1429             :   DCHECK_LE(Bytecodes::SizeForUnsignedOperand(function_id),
    1430             :             OperandSize::kShort);
    1431     1245550 :   if (IntrinsicsHelper::IsSupported(function_id)) {
    1432             :     IntrinsicsHelper::IntrinsicId intrinsic_id =
    1433       70983 :         IntrinsicsHelper::FromRuntimeId(function_id);
    1434             :     OutputInvokeIntrinsic(static_cast<int>(intrinsic_id), args,
    1435             :                           args.register_count());
    1436             :   } else {
    1437             :     OutputCallRuntime(static_cast<int>(function_id), args,
    1438             :                       args.register_count());
    1439             :   }
    1440     1245576 :   return *this;
    1441             : }
    1442             : 
    1443      399505 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1444             :     Runtime::FunctionId function_id, Register arg) {
    1445      399505 :   return CallRuntime(function_id, RegisterList(arg));
    1446             : }
    1447             : 
    1448       85919 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1449             :     Runtime::FunctionId function_id) {
    1450       85919 :   return CallRuntime(function_id, RegisterList());
    1451             : }
    1452             : 
    1453        4561 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
    1454             :     Runtime::FunctionId function_id, RegisterList args,
    1455             :     RegisterList return_pair) {
    1456             :   DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
    1457             :   DCHECK_LE(Bytecodes::SizeForUnsignedOperand(function_id),
    1458             :             OperandSize::kShort);
    1459             :   DCHECK_EQ(2, return_pair.register_count());
    1460             :   OutputCallRuntimeForPair(static_cast<uint16_t>(function_id), args,
    1461             :                            args.register_count(), return_pair);
    1462        4561 :   return *this;
    1463             : }
    1464             : 
    1465        4560 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
    1466             :     Runtime::FunctionId function_id, Register arg, RegisterList return_pair) {
    1467        4560 :   return CallRuntimeForPair(function_id, RegisterList(arg), return_pair);
    1468             : }
    1469             : 
    1470         414 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
    1471             :                                                           RegisterList args) {
    1472             :   OutputCallJSRuntime(context_index, args, args.register_count());
    1473         415 :   return *this;
    1474             : }
    1475             : 
    1476        4416 : BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
    1477             :                                                    LanguageMode language_mode) {
    1478        4416 :   if (language_mode == LanguageMode::kSloppy) {
    1479             :     OutputDeletePropertySloppy(object);
    1480             :   } else {
    1481             :     DCHECK_EQ(language_mode, LanguageMode::kStrict);
    1482             :     OutputDeletePropertyStrict(object);
    1483             :   }
    1484        4416 :   return *this;
    1485             : }
    1486             : 
    1487           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(
    1488             :     const AstRawString* raw_string) {
    1489    15363627 :   return constant_array_builder()->Insert(raw_string);
    1490             : }
    1491             : 
    1492           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(AstBigInt bigint) {
    1493       10475 :   return constant_array_builder()->Insert(bigint);
    1494             : }
    1495             : 
    1496           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(const Scope* scope) {
    1497      328722 :   return constant_array_builder()->Insert(scope);
    1498             : }
    1499             : 
    1500           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(double number) {
    1501      612370 :   return constant_array_builder()->Insert(number);
    1502             : }
    1503             : 
    1504             : #define ENTRY_GETTER(NAME, ...)                            \
    1505             :   size_t BytecodeArrayBuilder::NAME##ConstantPoolEntry() { \
    1506             :     return constant_array_builder()->Insert##NAME();       \
    1507             :   }
    1508      170177 : SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER)
    1509             : #undef ENTRY_GETTER
    1510             : 
    1511       20230 : BytecodeJumpTable* BytecodeArrayBuilder::AllocateJumpTable(
    1512             :     int size, int case_value_base) {
    1513             :   DCHECK_GT(size, 0);
    1514             : 
    1515       40460 :   size_t constant_pool_index = constant_array_builder()->InsertJumpTable(size);
    1516             : 
    1517             :   return new (zone())
    1518       20229 :       BytecodeJumpTable(constant_pool_index, size, case_value_base, zone());
    1519             : }
    1520             : 
    1521     3256250 : size_t BytecodeArrayBuilder::AllocateDeferredConstantPoolEntry() {
    1522     3256250 :   return constant_array_builder()->InsertDeferred();
    1523             : }
    1524             : 
    1525     2910713 : void BytecodeArrayBuilder::SetDeferredConstantPoolEntry(size_t entry,
    1526             :                                                         Handle<Object> object) {
    1527     2910713 :   constant_array_builder()->SetDeferredAt(entry, object);
    1528     2910703 : }
    1529             : 
    1530           0 : bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
    1531           0 :   if (!reg.is_valid()) {
    1532             :     return false;
    1533             :   }
    1534             : 
    1535           0 :   if (reg.is_current_context() || reg.is_function_closure()) {
    1536             :     return true;
    1537           0 :   } else if (reg.is_parameter()) {
    1538           0 :     int parameter_index = reg.ToParameterIndex(parameter_count());
    1539           0 :     return parameter_index >= 0 && parameter_index < parameter_count();
    1540           0 :   } else if (reg.index() < fixed_register_count()) {
    1541             :     return true;
    1542             :   } else {
    1543           0 :     return register_allocator()->RegisterIsLive(reg);
    1544             :   }
    1545             : }
    1546             : 
    1547           0 : bool BytecodeArrayBuilder::RegisterListIsValid(RegisterList reg_list) const {
    1548           0 :   if (reg_list.register_count() == 0) {
    1549             :     return reg_list.first_register() == Register(0);
    1550             :   } else {
    1551             :     int first_reg_index = reg_list.first_register().index();
    1552           0 :     for (int i = 0; i < reg_list.register_count(); i++) {
    1553           0 :       if (!RegisterIsValid(Register(first_reg_index + i))) {
    1554             :         return false;
    1555             :       }
    1556             :     }
    1557             :     return true;
    1558             :   }
    1559             : }
    1560             : 
    1561             : template <Bytecode bytecode, AccumulatorUse accumulator_use>
    1562    53193848 : void BytecodeArrayBuilder::PrepareToOutputBytecode() {
    1563    51994496 :   if (register_optimizer_)
    1564             :     register_optimizer_->PrepareForBytecode<bytecode, accumulator_use>();
    1565    53194044 : }
    1566             : 
    1567           0 : uint32_t BytecodeArrayBuilder::GetInputRegisterOperand(Register reg) {
    1568             :   DCHECK(RegisterIsValid(reg));
    1569    16050863 :   if (register_optimizer_) reg = register_optimizer_->GetInputRegister(reg);
    1570    16050805 :   return static_cast<uint32_t>(reg.ToOperand());
    1571             : }
    1572             : 
    1573           0 : uint32_t BytecodeArrayBuilder::GetOutputRegisterOperand(Register reg) {
    1574             :   DCHECK(RegisterIsValid(reg));
    1575      352640 :   if (register_optimizer_) register_optimizer_->PrepareOutputRegister(reg);
    1576      352642 :   return static_cast<uint32_t>(reg.ToOperand());
    1577             : }
    1578             : 
    1579     2891313 : uint32_t BytecodeArrayBuilder::GetInputRegisterListOperand(
    1580             :     RegisterList reg_list) {
    1581             :   DCHECK(RegisterListIsValid(reg_list));
    1582     2891313 :   if (register_optimizer_)
    1583     2890650 :     reg_list = register_optimizer_->GetInputRegisterList(reg_list);
    1584     2891354 :   return static_cast<uint32_t>(reg_list.first_register().ToOperand());
    1585             : }
    1586             : 
    1587           0 : uint32_t BytecodeArrayBuilder::GetOutputRegisterListOperand(
    1588             :     RegisterList reg_list) {
    1589             :   DCHECK(RegisterListIsValid(reg_list));
    1590       33273 :   if (register_optimizer_)
    1591       33272 :     register_optimizer_->PrepareOutputRegisterList(reg_list);
    1592       33274 :   return static_cast<uint32_t>(reg_list.first_register().ToOperand());
    1593             : }
    1594             : 
    1595           0 : std::ostream& operator<<(std::ostream& os,
    1596             :                          const BytecodeArrayBuilder::ToBooleanMode& mode) {
    1597           0 :   switch (mode) {
    1598             :     case BytecodeArrayBuilder::ToBooleanMode::kAlreadyBoolean:
    1599           0 :       return os << "AlreadyBoolean";
    1600             :     case BytecodeArrayBuilder::ToBooleanMode::kConvertToBoolean:
    1601           0 :       return os << "ConvertToBoolean";
    1602             :   }
    1603           0 :   UNREACHABLE();
    1604             : }
    1605             : 
    1606             : }  // namespace interpreter
    1607             : }  // namespace internal
    1608      121996 : }  // namespace v8

Generated by: LCOV version 1.10