LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-array-builder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 423 456 92.8 %
Date: 2017-10-20 Functions: 288 302 95.4 %

          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             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace interpreter {
      20             : 
      21             : class RegisterTransferWriter final
      22             :     : public NON_EXPORTED_BASE(BytecodeRegisterOptimizer::BytecodeWriter),
      23             :       public NON_EXPORTED_BASE(ZoneObject) {
      24             :  public:
      25     2154155 :   RegisterTransferWriter(BytecodeArrayBuilder* builder) : builder_(builder) {}
      26           0 :   ~RegisterTransferWriter() override {}
      27             : 
      28     2384671 :   void EmitLdar(Register input) override { builder_->OutputLdarRaw(input); }
      29             : 
      30    19054270 :   void EmitStar(Register output) override { builder_->OutputStarRaw(output); }
      31             : 
      32     1698720 :   void EmitMov(Register input, Register output) override {
      33     1698720 :     builder_->OutputMovRaw(input, output);
      34     1698720 :   }
      35             : 
      36             :  private:
      37             :   BytecodeArrayBuilder* builder_;
      38             : };
      39             : 
      40     2154788 : BytecodeArrayBuilder::BytecodeArrayBuilder(
      41             :     Isolate* isolate, Zone* zone, int parameter_count, int locals_count,
      42             :     FeedbackVectorSpec* feedback_vector_spec,
      43             :     SourcePositionTableBuilder::RecordingMode source_position_mode)
      44             :     : zone_(zone),
      45             :       feedback_vector_spec_(feedback_vector_spec),
      46             :       bytecode_generated_(false),
      47             :       constant_array_builder_(zone),
      48             :       handler_table_builder_(zone),
      49             :       return_seen_in_block_(false),
      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     4309578 :       register_optimizer_(nullptr) {
      56             :   DCHECK_GE(parameter_count_, 0);
      57             :   DCHECK_GE(local_register_count_, 0);
      58             : 
      59     2154794 :   if (FLAG_ignition_reo) {
      60             :     register_optimizer_ = new (zone) BytecodeRegisterOptimizer(
      61             :         zone, &register_allocator_, fixed_register_count(), parameter_count,
      62     2154155 :         new (zone) RegisterTransferWriter(this));
      63             :   }
      64     2154793 : }
      65             : 
      66     2178086 : 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     2178086 :   return Register::FromParameterIndex(parameter_index + 1, parameter_count());
      71             : }
      72             : 
      73      505592 : Register BytecodeArrayBuilder::Receiver() const {
      74      505592 :   return Register::FromParameterIndex(0, parameter_count());
      75             : }
      76             : 
      77     6472262 : Register BytecodeArrayBuilder::Local(int index) const {
      78             :   // TODO(marja): Make a DCHECK once crbug.com/706234 is fixed.
      79     6472262 :   CHECK_LT(index, locals_count());
      80     6472262 :   return Register(index);
      81             : }
      82             : 
      83     4307743 : Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
      84             :   DCHECK(return_seen_in_block_);
      85             :   DCHECK(!bytecode_generated_);
      86     2153871 :   bytecode_generated_ = true;
      87             : 
      88             :   int register_count = total_register_count();
      89             : 
      90     4307104 :   if (register_optimizer_) {
      91     2153233 :     register_optimizer_->Flush();
      92     4306466 :     register_count = register_optimizer_->maxiumum_register_index() + 1;
      93             :   }
      94             : 
      95             :   Handle<FixedArray> handler_table =
      96     2153871 :       handler_table_builder()->ToHandlerTable(isolate);
      97             :   return bytecode_array_writer_.ToBytecodeArray(
      98     2153872 :       isolate, register_count, parameter_count(), handler_table);
      99             : }
     100             : 
     101             : BytecodeSourceInfo BytecodeArrayBuilder::CurrentSourcePosition(
     102             :     Bytecode bytecode) {
     103    79098993 :   BytecodeSourceInfo source_position;
     104    79099000 :   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    97315439 :     if (latest_source_info_.is_statement() ||
     110    60748557 :         !FLAG_ignition_filter_expression_positions ||
     111    24184391 :         !Bytecodes::IsWithoutExternalSideEffects(bytecode)) {
     112    28119061 :       source_position = latest_source_info_;
     113    28119061 :       latest_source_info_.set_invalid();
     114             :     }
     115             :   }
     116    79099009 :   return source_position;
     117             : }
     118             : 
     119           0 : void BytecodeArrayBuilder::SetDeferredSourceInfo(
     120             :     BytecodeSourceInfo source_info) {
     121    31744009 :   if (!source_info.is_valid()) return;
     122     2043543 :   deferred_source_info_ = source_info;
     123             : }
     124             : 
     125           0 : void BytecodeArrayBuilder::AttachOrEmitDeferredSourceInfo(BytecodeNode* node) {
     126    70492384 :   if (!deferred_source_info_.is_valid()) return;
     127     2033066 :   if (!node->source_info().is_valid()) {
     128             :     node->set_source_info(deferred_source_info_);
     129      605477 :   } 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    68014072 : void BytecodeArrayBuilder::Write(BytecodeNode* node) {
     139             :   AttachOrEmitDeferredSourceInfo(node);
     140    68014072 :   bytecode_array_writer_.Write(node);
     141    68014165 : }
     142             : 
     143     2449618 : void BytecodeArrayBuilder::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
     144             :   AttachOrEmitDeferredSourceInfo(node);
     145     2449618 :   bytecode_array_writer_.WriteJump(node, label);
     146     2449619 : }
     147             : 
     148       28694 : void BytecodeArrayBuilder::WriteSwitch(BytecodeNode* node,
     149             :                                        BytecodeJumpTable* jump_table) {
     150             :   AttachOrEmitDeferredSourceInfo(node);
     151       28694 :   bytecode_array_writer_.WriteSwitch(node, jump_table);
     152       28694 : }
     153             : 
     154     2384671 : void BytecodeArrayBuilder::OutputLdarRaw(Register reg) {
     155     2384671 :   uint32_t operand = static_cast<uint32_t>(reg.ToOperand());
     156             :   BytecodeNode node(BytecodeNode::Ldar(BytecodeSourceInfo(), operand));
     157     2384672 :   Write(&node);
     158     2384672 : }
     159             : 
     160    19054270 : void BytecodeArrayBuilder::OutputStarRaw(Register reg) {
     161    19054270 :   uint32_t operand = static_cast<uint32_t>(reg.ToOperand());
     162             :   BytecodeNode node(BytecodeNode::Star(BytecodeSourceInfo(), operand));
     163    19054273 :   Write(&node);
     164    19054277 : }
     165             : 
     166     1698720 : void BytecodeArrayBuilder::OutputMovRaw(Register src, Register dest) {
     167     1698720 :   uint32_t operand0 = static_cast<uint32_t>(src.ToOperand());
     168     1698720 :   uint32_t operand1 = static_cast<uint32_t>(dest.ToOperand());
     169             :   BytecodeNode node(
     170             :       BytecodeNode::Mov(BytecodeSourceInfo(), operand0, operand1));
     171     1698720 :   Write(&node);
     172     1698720 : }
     173             : 
     174             : namespace {
     175             : 
     176             : template <OperandTypeInfo type_info>
     177             : class UnsignedOperandHelper {
     178             :  public:
     179             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, size_t value)) {
     180             :     DCHECK(IsValid(value));
     181    37889594 :     return static_cast<uint32_t>(value);
     182             :   }
     183             : 
     184             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, int value)) {
     185             :     DCHECK_GE(value, 0);
     186    34042100 :     return Convert(builder, static_cast<size_t>(value));
     187             :   }
     188             : 
     189             :  private:
     190             :   static bool IsValid(size_t value) {
     191             :     switch (type_info) {
     192             :       case OperandTypeInfo::kFixedUnsignedByte:
     193             :         return value <= kMaxUInt8;
     194             :       case OperandTypeInfo::kFixedUnsignedShort:
     195             :         return value <= kMaxUInt16;
     196             :       case OperandTypeInfo::kScalableUnsignedByte:
     197             :         return value <= kMaxUInt32;
     198             :       default:
     199             :         UNREACHABLE();
     200             :     }
     201             :   }
     202             : };
     203             : 
     204             : template <OperandType>
     205             : class OperandHelper {};
     206             : 
     207             : #define DEFINE_UNSIGNED_OPERAND_HELPER(Name, Type) \
     208             :   template <>                                      \
     209             :   class OperandHelper<OperandType::k##Name>        \
     210             :       : public UnsignedOperandHelper<Type> {};
     211             : UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER)
     212             : UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER)
     213             : #undef DEFINE_UNSIGNED_OPERAND_HELPER
     214             : 
     215             : template <>
     216             : class OperandHelper<OperandType::kImm> {
     217             :  public:
     218             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, int value)) {
     219     5170098 :     return static_cast<uint32_t>(value);
     220             :   }
     221             : };
     222             : 
     223             : template <>
     224             : class OperandHelper<OperandType::kReg> {
     225             :  public:
     226             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, Register reg)) {
     227    11748077 :     return builder->GetInputRegisterOperand(reg);
     228             :   }
     229             : };
     230             : 
     231             : template <>
     232             : class OperandHelper<OperandType::kRegList> {
     233             :  public:
     234             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder,
     235             :                                  RegisterList reg_list)) {
     236     1806235 :     return builder->GetInputRegisterListOperand(reg_list);
     237             :   }
     238             : };
     239             : 
     240             : template <>
     241             : class OperandHelper<OperandType::kRegPair> {
     242             :  public:
     243             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder,
     244             :                                  RegisterList reg_list)) {
     245             :     DCHECK_EQ(reg_list.register_count(), 2);
     246        6073 :     return builder->GetInputRegisterListOperand(reg_list);
     247             :   }
     248             : };
     249             : 
     250             : template <>
     251             : class OperandHelper<OperandType::kRegOut> {
     252             :  public:
     253             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, Register reg)) {
     254      634853 :     return builder->GetOutputRegisterOperand(reg);
     255             :   }
     256             : };
     257             : 
     258             : template <>
     259             : class OperandHelper<OperandType::kRegOutList> {
     260             :  public:
     261             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder,
     262             :                                  RegisterList reg_list)) {
     263       20047 :     return builder->GetOutputRegisterListOperand(reg_list);
     264             :   }
     265             : };
     266             : 
     267             : template <>
     268             : class OperandHelper<OperandType::kRegOutPair> {
     269             :  public:
     270             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder,
     271             :                                  RegisterList reg_list)) {
     272             :     DCHECK_EQ(2, reg_list.register_count());
     273        2150 :     return builder->GetOutputRegisterListOperand(reg_list);
     274             :   }
     275             : };
     276             : 
     277             : template <>
     278             : class OperandHelper<OperandType::kRegOutTriple> {
     279             :  public:
     280             :   INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder,
     281             :                                  RegisterList reg_list)) {
     282             :     DCHECK_EQ(3, reg_list.register_count());
     283        6081 :     return builder->GetOutputRegisterListOperand(reg_list);
     284             :   }
     285             : };
     286             : 
     287             : }  // namespace
     288             : 
     289             : template <Bytecode bytecode, AccumulatorUse accumulator_use,
     290             :           OperandType... operand_types>
     291             : class BytecodeNodeBuilder {
     292             :  public:
     293             :   template <typename... Operands>
     294     1534982 :   INLINE(static BytecodeNode Make(BytecodeArrayBuilder* builder,
     295             :                                   Operands... operands)) {
     296             :     static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands,
     297             :                   "too many operands for bytecode");
     298    47354985 :     builder->PrepareToOutputBytecode<bytecode, accumulator_use>();
     299             :     // The "OperandHelper<operand_types>::Convert(builder, operands)..." will
     300             :     // expand both the OperandType... and Operands... parameter packs e.g. for:
     301             :     //   BytecodeNodeBuilder<OperandType::kReg, OperandType::kImm>::Make<
     302             :     //       Register, int>(..., Register reg, int immediate)
     303             :     // the code will expand into:
     304             :     //    OperandHelper<OperandType::kReg>::Convert(builder, reg),
     305             :     //    OperandHelper<OperandType::kImm>::Convert(builder, immediate),
     306             :     return BytecodeNode::Create<bytecode, accumulator_use, operand_types...>(
     307             :         builder->CurrentSourcePosition(bytecode),
     308      401142 :         OperandHelper<operand_types>::Convert(builder, operands)...);
     309             :   }
     310             : };
     311             : 
     312             : #define DEFINE_BYTECODE_OUTPUT(name, ...)                             \
     313             :   template <typename... Operands>                                     \
     314             :   BytecodeNode BytecodeArrayBuilder::Create##name##Node(              \
     315             :       Operands... operands) {                                         \
     316             :     return BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make( \
     317             :         this, operands...);                                           \
     318             :   }                                                                   \
     319             :                                                                       \
     320             :   template <typename... Operands>                                     \
     321             :   void BytecodeArrayBuilder::Output##name(Operands... operands) {     \
     322             :     BytecodeNode node(Create##name##Node(operands...));               \
     323             :     Write(&node);                                                     \
     324             :   }                                                                   \
     325             :                                                                       \
     326             :   template <typename... Operands>                                     \
     327             :   void BytecodeArrayBuilder::Output##name(BytecodeLabel* label,       \
     328             :                                           Operands... operands) {     \
     329             :     DCHECK(Bytecodes::IsJump(Bytecode::k##name));                     \
     330             :     BytecodeNode node(Create##name##Node(operands...));               \
     331             :     WriteJump(&node, label);                                          \
     332             :     LeaveBasicBlock();                                                \
     333             :   }
     334    47326307 : BYTECODE_LIST(DEFINE_BYTECODE_OUTPUT)
     335             : #undef DEFINE_BYTECODE_OUTPUT
     336             : 
     337             : void BytecodeArrayBuilder::OutputSwitchOnSmiNoFeedback(
     338       86082 :     BytecodeJumpTable* jump_table) {
     339             :   BytecodeNode node(CreateSwitchOnSmiNoFeedbackNode(
     340             :       jump_table->constant_pool_index(), jump_table->size(),
     341       86082 :       jump_table->case_value_base()));
     342       28694 :   WriteSwitch(&node, jump_table);
     343       28694 :   LeaveBasicBlock();
     344             : }
     345             : 
     346      709699 : BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
     347             :                                                             Register reg,
     348             :                                                             int feedback_slot) {
     349      709699 :   switch (op) {
     350             :     case Token::Value::ADD:
     351             :       OutputAdd(reg, feedback_slot);
     352             :       break;
     353             :     case Token::Value::SUB:
     354             :       OutputSub(reg, feedback_slot);
     355             :       break;
     356             :     case Token::Value::MUL:
     357             :       OutputMul(reg, feedback_slot);
     358             :       break;
     359             :     case Token::Value::DIV:
     360             :       OutputDiv(reg, feedback_slot);
     361             :       break;
     362             :     case Token::Value::MOD:
     363             :       OutputMod(reg, feedback_slot);
     364             :       break;
     365             :     case Token::Value::BIT_OR:
     366             :       OutputBitwiseOr(reg, feedback_slot);
     367             :       break;
     368             :     case Token::Value::BIT_XOR:
     369             :       OutputBitwiseXor(reg, feedback_slot);
     370             :       break;
     371             :     case Token::Value::BIT_AND:
     372             :       OutputBitwiseAnd(reg, feedback_slot);
     373             :       break;
     374             :     case Token::Value::SHL:
     375             :       OutputShiftLeft(reg, feedback_slot);
     376             :       break;
     377             :     case Token::Value::SAR:
     378             :       OutputShiftRight(reg, feedback_slot);
     379             :       break;
     380             :     case Token::Value::SHR:
     381             :       OutputShiftRightLogical(reg, feedback_slot);
     382             :       break;
     383             :     default:
     384           0 :       UNREACHABLE();
     385             :   }
     386      709700 :   return *this;
     387             : }
     388             : 
     389      207306 : BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperationSmiLiteral(
     390             :     Token::Value op, Smi* literal, int feedback_slot) {
     391      207306 :   switch (op) {
     392             :     case Token::Value::ADD:
     393             :       OutputAddSmi(literal->value(), feedback_slot);
     394             :       break;
     395             :     case Token::Value::SUB:
     396             :       OutputSubSmi(literal->value(), feedback_slot);
     397             :       break;
     398             :     case Token::Value::MUL:
     399             :       OutputMulSmi(literal->value(), feedback_slot);
     400             :       break;
     401             :     case Token::Value::DIV:
     402             :       OutputDivSmi(literal->value(), feedback_slot);
     403             :       break;
     404             :     case Token::Value::MOD:
     405             :       OutputModSmi(literal->value(), feedback_slot);
     406             :       break;
     407             :     case Token::Value::BIT_OR:
     408             :       OutputBitwiseOrSmi(literal->value(), feedback_slot);
     409             :       break;
     410             :     case Token::Value::BIT_XOR:
     411             :       OutputBitwiseXorSmi(literal->value(), feedback_slot);
     412             :       break;
     413             :     case Token::Value::BIT_AND:
     414             :       OutputBitwiseAndSmi(literal->value(), feedback_slot);
     415             :       break;
     416             :     case Token::Value::SHL:
     417             :       OutputShiftLeftSmi(literal->value(), feedback_slot);
     418             :       break;
     419             :     case Token::Value::SAR:
     420             :       OutputShiftRightSmi(literal->value(), feedback_slot);
     421             :       break;
     422             :     case Token::Value::SHR:
     423             :       OutputShiftRightLogicalSmi(literal->value(), feedback_slot);
     424             :       break;
     425             :     default:
     426           0 :       UNREACHABLE();
     427             :   }
     428      207306 :   return *this;
     429             : }
     430             : 
     431      253726 : BytecodeArrayBuilder& BytecodeArrayBuilder::UnaryOperation(Token::Value op,
     432             :                                                            int feedback_slot) {
     433      253726 :   switch (op) {
     434             :     case Token::Value::INC:
     435             :       OutputInc(feedback_slot);
     436             :       break;
     437             :     case Token::Value::DEC:
     438             :       OutputDec(feedback_slot);
     439             :       break;
     440             :     case Token::Value::ADD:
     441             :       OutputToNumber(feedback_slot);
     442             :       break;
     443             :     case Token::Value::SUB:
     444             :       OutputNegate(feedback_slot);
     445             :       break;
     446             :     case Token::Value::BIT_NOT:
     447             :       OutputBitwiseNot(feedback_slot);
     448             :       break;
     449             :     default:
     450           0 :       UNREACHABLE();
     451             :   }
     452      253726 :   return *this;
     453             : }
     454             : 
     455       61449 : BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot(ToBooleanMode mode) {
     456       61449 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
     457             :     OutputLogicalNot();
     458             :   } else {
     459             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
     460             :     OutputToBooleanLogicalNot();
     461             :   }
     462       61449 :   return *this;
     463             : }
     464             : 
     465       57825 : BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
     466             :   OutputTypeOf();
     467       57825 :   return *this;
     468             : }
     469             : 
     470        3763 : BytecodeArrayBuilder& BytecodeArrayBuilder::GetSuperConstructor(Register out) {
     471             :   OutputGetSuperConstructor(out);
     472        3763 :   return *this;
     473             : }
     474             : 
     475      959147 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
     476             :     Token::Value op, Register reg, int feedback_slot) {
     477      959147 :   switch (op) {
     478             :     case Token::Value::EQ:
     479             :       OutputTestEqual(reg, feedback_slot);
     480             :       break;
     481             :     case Token::Value::EQ_STRICT:
     482             :       OutputTestEqualStrict(reg, feedback_slot);
     483             :       break;
     484             :     case Token::Value::LT:
     485             :       OutputTestLessThan(reg, feedback_slot);
     486             :       break;
     487             :     case Token::Value::GT:
     488             :       OutputTestGreaterThan(reg, feedback_slot);
     489             :       break;
     490             :     case Token::Value::LTE:
     491             :       OutputTestLessThanOrEqual(reg, feedback_slot);
     492             :       break;
     493             :     case Token::Value::GTE:
     494             :       OutputTestGreaterThanOrEqual(reg, feedback_slot);
     495             :       break;
     496             :     default:
     497           0 :       UNREACHABLE();
     498             :   }
     499      959147 :   return *this;
     500             : }
     501             : 
     502       68189 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
     503             :                                                              Register reg) {
     504       68189 :   switch (op) {
     505             :     case Token::Value::EQ_STRICT:
     506             :       OutputTestEqualStrictNoFeedback(reg);
     507             :       break;
     508             :     case Token::Value::INSTANCEOF:
     509             :       OutputTestInstanceOf(reg);
     510             :       break;
     511             :     case Token::Value::IN:
     512             :       OutputTestIn(reg);
     513             :       break;
     514             :     default:
     515           0 :       UNREACHABLE();
     516             :   }
     517       68189 :   return *this;
     518             : }
     519             : 
     520       32054 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareUndetectable() {
     521             :   OutputTestUndetectable();
     522       32054 :   return *this;
     523             : }
     524             : 
     525        8935 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareUndefined() {
     526             :   OutputTestUndefined();
     527        8935 :   return *this;
     528             : }
     529             : 
     530        1032 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareNull() {
     531             :   OutputTestNull();
     532        1032 :   return *this;
     533             : }
     534             : 
     535       11839 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareNil(Token::Value op,
     536             :                                                        NilValue nil) {
     537       11839 :   if (op == Token::EQ) {
     538        1874 :     return CompareUndetectable();
     539             :   } else {
     540             :     DCHECK_EQ(Token::EQ_STRICT, op);
     541        9965 :     if (nil == kUndefinedValue) {
     542        8934 :       return CompareUndefined();
     543             :     } else {
     544             :       DCHECK_EQ(kNullValue, nil);
     545        1031 :       return CompareNull();
     546             :     }
     547             :   }
     548             : }
     549             : 
     550      145417 : BytecodeArrayBuilder& BytecodeArrayBuilder::CompareTypeOf(
     551             :     TestTypeOfFlags::LiteralFlag literal_flag) {
     552             :   DCHECK_NE(literal_flag, TestTypeOfFlags::LiteralFlag::kOther);
     553      145417 :   OutputTestTypeOf(TestTypeOfFlags::Encode(literal_flag));
     554      145417 :   return *this;
     555             : }
     556             : 
     557       88918 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadConstantPoolEntry(
     558             :     size_t entry) {
     559             :   OutputLdaConstant(entry);
     560       88918 :   return *this;
     561             : }
     562             : 
     563     6125631 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
     564             :     v8::internal::Smi* smi) {
     565             :   int32_t raw_smi = smi->value();
     566     6125631 :   if (raw_smi == 0) {
     567             :     OutputLdaZero();
     568             :   } else {
     569             :     OutputLdaSmi(raw_smi);
     570             :   }
     571     6125632 :   return *this;
     572             : }
     573             : 
     574     2458519 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
     575             :     const AstRawString* raw_string) {
     576             :   size_t entry = GetConstantPoolEntry(raw_string);
     577             :   OutputLdaConstant(entry);
     578     2458520 :   return *this;
     579             : }
     580             : 
     581        8659 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(const Scope* scope) {
     582             :   size_t entry = GetConstantPoolEntry(scope);
     583             :   OutputLdaConstant(entry);
     584        8659 :   return *this;
     585             : }
     586             : 
     587     8409022 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
     588     8409022 :     const AstValue* ast_value) {
     589     8409022 :   if (ast_value->IsSmi()) {
     590     5037680 :     return LoadLiteral(ast_value->AsSmi());
     591     3371342 :   } else if (ast_value->IsUndefined()) {
     592      121061 :     return LoadUndefined();
     593     3250281 :   } else if (ast_value->IsTrue()) {
     594      119650 :     return LoadTrue();
     595     3130631 :   } else if (ast_value->IsFalse()) {
     596      211012 :     return LoadFalse();
     597     2919619 :   } else if (ast_value->IsNull()) {
     598       31534 :     return LoadNull();
     599     2888085 :   } else if (ast_value->IsTheHole()) {
     600           0 :     return LoadTheHole();
     601     2888085 :   } else if (ast_value->IsString()) {
     602     2159802 :     return LoadLiteral(ast_value->AsString());
     603      728283 :   } else if (ast_value->IsHeapNumber() || ast_value->IsBigInt()) {
     604             :     size_t entry = GetConstantPoolEntry(ast_value);
     605             :     OutputLdaConstant(entry);
     606      726438 :     return *this;
     607             :   } else {
     608             :     // This should be the only ast value type left.
     609             :     DCHECK(ast_value->IsSymbol());
     610             :     size_t entry;
     611        1845 :     switch (ast_value->AsSymbol()) {
     612             :       case AstSymbol::kHomeObjectSymbol:
     613             :         entry = HomeObjectSymbolConstantPoolEntry();
     614        1845 :         break;
     615             :         // No default case so that we get a warning if AstSymbol changes
     616             :     }
     617             :     OutputLdaConstant(entry);
     618        1845 :     return *this;
     619             :   }
     620             : }
     621             : 
     622      619088 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() {
     623             :   OutputLdaUndefined();
     624      619088 :   return *this;
     625             : }
     626             : 
     627       34962 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() {
     628             :   OutputLdaNull();
     629       34962 :   return *this;
     630             : }
     631             : 
     632      579310 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
     633             :   OutputLdaTheHole();
     634      579310 :   return *this;
     635             : }
     636             : 
     637      122001 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
     638             :   OutputLdaTrue();
     639      122001 :   return *this;
     640             : }
     641             : 
     642      215999 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
     643             :   OutputLdaFalse();
     644      215999 :   return *this;
     645             : }
     646             : 
     647         371 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBoolean(bool value) {
     648         371 :   return value ? LoadTrue() : LoadFalse();
     649             : }
     650             : 
     651     7838618 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
     652             :     Register reg) {
     653     7838618 :   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     7836234 :     register_optimizer_->DoLdar(reg);
     658             :   } else {
     659             :     OutputLdar(reg);
     660             :   }
     661     7838628 :   return *this;
     662             : }
     663             : 
     664    23185709 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
     665             :     Register reg) {
     666    23185709 :   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    23181004 :     register_optimizer_->DoStar(reg);
     671             :   } else {
     672             :     OutputStar(reg);
     673             :   }
     674    23185719 :   return *this;
     675             : }
     676             : 
     677      727221 : BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
     678             :                                                          Register to) {
     679             :   DCHECK(from != to);
     680      727221 :   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      726771 :     register_optimizer_->DoMov(from, to);
     685             :   } else {
     686             :     OutputMov(from, to);
     687             :   }
     688      727221 :   return *this;
     689             : }
     690             : 
     691     2431448 : 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     2431448 :   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     2431448 :   return *this;
     706             : }
     707             : 
     708     1064787 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
     709             :     const AstRawString* name, int feedback_slot, LanguageMode language_mode) {
     710             :   size_t name_index = GetConstantPoolEntry(name);
     711     1064787 :   if (language_mode == LanguageMode::kSloppy) {
     712             :     OutputStaGlobalSloppy(name_index, feedback_slot);
     713             :   } else {
     714             :     DCHECK_EQ(language_mode, LanguageMode::kStrict);
     715             :     OutputStaGlobalStrict(name_index, feedback_slot);
     716             :   }
     717     1064787 :   return *this;
     718             : }
     719             : 
     720     2841759 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(
     721             :     Register context, int slot_index, int depth,
     722             :     ContextSlotMutability mutability) {
     723     2841759 :   if (context.is_current_context() && depth == 0) {
     724     2717557 :     if (mutability == kImmutableSlot) {
     725             :       OutputLdaImmutableCurrentContextSlot(slot_index);
     726             :     } else {
     727             :       DCHECK_EQ(kMutableSlot, mutability);
     728             :       OutputLdaCurrentContextSlot(slot_index);
     729             :     }
     730      124202 :   } else if (mutability == kImmutableSlot) {
     731             :     OutputLdaImmutableContextSlot(context, slot_index, depth);
     732             :   } else {
     733             :     DCHECK_EQ(mutability, kMutableSlot);
     734             :     OutputLdaContextSlot(context, slot_index, depth);
     735             :   }
     736     2841758 :   return *this;
     737             : }
     738             : 
     739     2595832 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
     740             :                                                              int slot_index,
     741             :                                                              int depth) {
     742     2595832 :   if (context.is_current_context() && depth == 0) {
     743             :     OutputStaCurrentContextSlot(slot_index);
     744             :   } else {
     745             :     OutputStaContextSlot(context, slot_index, depth);
     746             :   }
     747     2595832 :   return *this;
     748             : }
     749             : 
     750       11815 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
     751             :     const AstRawString* name, TypeofMode typeof_mode) {
     752             :   size_t name_index = GetConstantPoolEntry(name);
     753       11815 :   if (typeof_mode == INSIDE_TYPEOF) {
     754             :     OutputLdaLookupSlotInsideTypeof(name_index);
     755             :   } else {
     756             :     DCHECK_EQ(typeof_mode, NOT_INSIDE_TYPEOF);
     757             :     OutputLdaLookupSlot(name_index);
     758             :   }
     759       11815 :   return *this;
     760             : }
     761             : 
     762        3834 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupContextSlot(
     763             :     const AstRawString* name, TypeofMode typeof_mode, int slot_index,
     764             :     int depth) {
     765             :   size_t name_index = GetConstantPoolEntry(name);
     766        3834 :   if (typeof_mode == INSIDE_TYPEOF) {
     767             :     OutputLdaLookupContextSlotInsideTypeof(name_index, slot_index, depth);
     768             :   } else {
     769             :     DCHECK(typeof_mode == NOT_INSIDE_TYPEOF);
     770             :     OutputLdaLookupContextSlot(name_index, slot_index, depth);
     771             :   }
     772        3834 :   return *this;
     773             : }
     774             : 
     775      365761 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupGlobalSlot(
     776             :     const AstRawString* name, TypeofMode typeof_mode, int feedback_slot,
     777             :     int depth) {
     778             :   size_t name_index = GetConstantPoolEntry(name);
     779      365761 :   if (typeof_mode == INSIDE_TYPEOF) {
     780             :     OutputLdaLookupGlobalSlotInsideTypeof(name_index, feedback_slot, depth);
     781             :   } else {
     782             :     DCHECK(typeof_mode == NOT_INSIDE_TYPEOF);
     783             :     OutputLdaLookupGlobalSlot(name_index, feedback_slot, depth);
     784             :   }
     785      365761 :   return *this;
     786             : }
     787             : 
     788       30941 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
     789             :     const AstRawString* name, LanguageMode language_mode,
     790             :     LookupHoistingMode lookup_hoisting_mode) {
     791             :   size_t name_index = GetConstantPoolEntry(name);
     792             :   uint8_t flags =
     793       30941 :       StoreLookupSlotFlags::Encode(language_mode, lookup_hoisting_mode);
     794             :   OutputStaLookupSlot(name_index, flags);
     795       30941 :   return *this;
     796             : }
     797             : 
     798     3518026 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
     799             :     Register object, const AstRawString* name, int feedback_slot) {
     800             :   size_t name_index = GetConstantPoolEntry(name);
     801             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     802     3518027 :   return *this;
     803             : }
     804             : 
     805      217432 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
     806             :     Register object, int feedback_slot) {
     807             :   OutputLdaKeyedProperty(object, feedback_slot);
     808      217432 :   return *this;
     809             : }
     810             : 
     811       26721 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadIteratorProperty(
     812             :     Register object, int feedback_slot) {
     813             :   size_t name_index = IteratorSymbolConstantPoolEntry();
     814             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     815       26721 :   return *this;
     816             : }
     817             : 
     818         330 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAsyncIteratorProperty(
     819             :     Register object, int feedback_slot) {
     820             :   size_t name_index = AsyncIteratorSymbolConstantPoolEntry();
     821             :   OutputLdaNamedProperty(object, name_index, feedback_slot);
     822         330 :   return *this;
     823             : }
     824             : 
     825      391769 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
     826             :     Register object, Register name, DataPropertyInLiteralFlags flags,
     827             :     int feedback_slot) {
     828             :   OutputStaDataPropertyInLiteral(object, name, flags, feedback_slot);
     829      391769 :   return *this;
     830             : }
     831             : 
     832         205 : BytecodeArrayBuilder& BytecodeArrayBuilder::CollectTypeProfile(int position) {
     833             :   OutputCollectTypeProfile(position);
     834         205 :   return *this;
     835             : }
     836             : 
     837     1657760 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
     838             :     Register object, size_t name_index, int feedback_slot,
     839             :     LanguageMode language_mode) {
     840             :   // Ensure that language mode is in sync with the IC slot kind.
     841             :   DCHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(
     842             :                 FeedbackVector::ToSlot(feedback_slot))),
     843             :             language_mode);
     844             :   OutputStaNamedProperty(object, name_index, feedback_slot);
     845     1657760 :   return *this;
     846             : }
     847             : 
     848     1537798 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
     849             :     Register object, const AstRawString* name, int feedback_slot,
     850             :     LanguageMode language_mode) {
     851             :   size_t name_index = GetConstantPoolEntry(name);
     852     1537798 :   return StoreNamedProperty(object, name_index, feedback_slot, language_mode);
     853             : }
     854             : 
     855      327969 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedOwnProperty(
     856             :     Register object, const AstRawString* name, int feedback_slot) {
     857             :   size_t name_index = GetConstantPoolEntry(name);
     858             :   // Ensure that the store operation is in sync with the IC slot kind.
     859             :   DCHECK_EQ(
     860             :       FeedbackSlotKind::kStoreOwnNamed,
     861             :       feedback_vector_spec()->GetKind(FeedbackVector::ToSlot(feedback_slot)));
     862             :   OutputStaNamedOwnProperty(object, name_index, feedback_slot);
     863      327969 :   return *this;
     864             : }
     865             : 
     866      345955 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
     867             :     Register object, Register key, int feedback_slot,
     868             :     LanguageMode language_mode) {
     869             :   // Ensure that language mode is in sync with the IC slot kind.
     870             :   DCHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(
     871             :                 FeedbackVector::ToSlot(feedback_slot))),
     872             :             language_mode);
     873             :   OutputStaKeyedProperty(object, key, feedback_slot);
     874      345955 :   return *this;
     875             : }
     876             : 
     877      119962 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreHomeObjectProperty(
     878             :     Register object, int feedback_slot, LanguageMode language_mode) {
     879             :   size_t name_index = HomeObjectSymbolConstantPoolEntry();
     880      119962 :   return StoreNamedProperty(object, name_index, feedback_slot, language_mode);
     881             : }
     882             : 
     883     3969996 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
     884             :     size_t shared_function_info_entry, int slot, int flags) {
     885             :   OutputCreateClosure(shared_function_info_entry, slot, flags);
     886     3969999 :   return *this;
     887             : }
     888             : 
     889       56532 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateBlockContext(
     890             :     const Scope* scope) {
     891             :   size_t entry = GetConstantPoolEntry(scope);
     892             :   OutputCreateBlockContext(entry);
     893       56532 :   return *this;
     894             : }
     895             : 
     896      102123 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateCatchContext(
     897             :     Register exception, const AstRawString* name, const Scope* scope) {
     898             :   size_t name_index = GetConstantPoolEntry(name);
     899             :   size_t scope_index = GetConstantPoolEntry(scope);
     900             :   OutputCreateCatchContext(exception, name_index, scope_index);
     901      102123 :   return *this;
     902             : }
     903             : 
     904      146653 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(int slots) {
     905             :   OutputCreateFunctionContext(slots);
     906      146653 :   return *this;
     907             : }
     908             : 
     909       20740 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEvalContext(int slots) {
     910             :   OutputCreateEvalContext(slots);
     911       20740 :   return *this;
     912             : }
     913             : 
     914        3025 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(
     915             :     Register object, const Scope* scope) {
     916             :   size_t scope_index = GetConstantPoolEntry(scope);
     917             :   OutputCreateWithContext(object, scope_index);
     918        3025 :   return *this;
     919             : }
     920             : 
     921       99690 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
     922             :     CreateArgumentsType type) {
     923       99690 :   switch (type) {
     924             :     case CreateArgumentsType::kMappedArguments:
     925             :       OutputCreateMappedArguments();
     926             :       break;
     927             :     case CreateArgumentsType::kUnmappedArguments:
     928             :       OutputCreateUnmappedArguments();
     929             :       break;
     930             :     case CreateArgumentsType::kRestParameter:
     931             :       OutputCreateRestParameter();
     932             :       break;
     933             :     default:
     934           0 :       UNREACHABLE();
     935             :   }
     936       99690 :   return *this;
     937             : }
     938             : 
     939       57589 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
     940             :     const AstRawString* pattern, int literal_index, int flags) {
     941             :   size_t pattern_entry = GetConstantPoolEntry(pattern);
     942             :   OutputCreateRegExpLiteral(pattern_entry, literal_index, flags);
     943       57589 :   return *this;
     944             : }
     945             : 
     946      137207 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyArrayLiteral(
     947             :     int literal_index) {
     948             :   OutputCreateEmptyArrayLiteral(literal_index);
     949      137207 :   return *this;
     950             : }
     951             : 
     952      111461 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
     953             :     size_t constant_elements_entry, int literal_index, int flags) {
     954             :   OutputCreateArrayLiteral(constant_elements_entry, literal_index, flags);
     955      111461 :   return *this;
     956             : }
     957             : 
     958      263563 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
     959             :     size_t constant_properties_entry, int literal_index, int flags,
     960             :     Register output) {
     961             :   OutputCreateObjectLiteral(constant_properties_entry, literal_index, flags,
     962             :                             output);
     963      263563 :   return *this;
     964             : }
     965             : 
     966       40225 : BytecodeArrayBuilder& BytecodeArrayBuilder::CreateEmptyObjectLiteral() {
     967             :   OutputCreateEmptyObjectLiteral();
     968       40225 :   return *this;
     969             : }
     970             : 
     971        1440 : BytecodeArrayBuilder& BytecodeArrayBuilder::GetTemplateObject(
     972             :     size_t template_object_description_entry) {
     973             :   OutputGetTemplateObject(template_object_description_entry);
     974        1440 :   return *this;
     975             : }
     976             : 
     977      346020 : BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
     978             :   OutputPushContext(context);
     979      346020 :   return *this;
     980             : }
     981             : 
     982      354028 : BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
     983             :   OutputPopContext(context);
     984      354028 :   return *this;
     985             : }
     986             : 
     987        9097 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToObject(Register out) {
     988             :   OutputToObject(out);
     989        9097 :   return *this;
     990             : }
     991             : 
     992        7253 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToName(Register out) {
     993             :   OutputToName(out);
     994        7253 :   return *this;
     995             : }
     996             : 
     997           1 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToNumber(int feedback_slot) {
     998             :   OutputToNumber(feedback_slot);
     999           1 :   return *this;
    1000             : }
    1001             : 
    1002       29056 : BytecodeArrayBuilder& BytecodeArrayBuilder::ToNumeric(int feedback_slot) {
    1003             :   OutputToNumeric(feedback_slot);
    1004       29056 :   return *this;
    1005             : }
    1006             : 
    1007     3003371 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
    1008             :   // Flush the register optimizer when binding a label to ensure all
    1009             :   // expected registers are valid when jumping to this label.
    1010     3003371 :   if (register_optimizer_) register_optimizer_->Flush();
    1011     3003373 :   bytecode_array_writer_.BindLabel(label);
    1012             :   LeaveBasicBlock();
    1013     3003372 :   return *this;
    1014             : }
    1015             : 
    1016           0 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
    1017             :                                                  BytecodeLabel* label) {
    1018           0 :   bytecode_array_writer_.BindLabel(target, label);
    1019             :   LeaveBasicBlock();
    1020           0 :   return *this;
    1021             : }
    1022             : 
    1023       62833 : BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeJumpTable* jump_table,
    1024             :                                                  int case_value) {
    1025             :   // Flush the register optimizer when binding a jump table entry to ensure
    1026             :   // all expected registers are valid when jumping to this location.
    1027       62833 :   if (register_optimizer_) register_optimizer_->Flush();
    1028       62833 :   bytecode_array_writer_.BindJumpTableEntry(jump_table, case_value);
    1029             :   LeaveBasicBlock();
    1030       62833 :   return *this;
    1031             : }
    1032             : 
    1033      553381 : BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
    1034             :   DCHECK(!label->is_bound());
    1035             :   OutputJump(label, 0);
    1036      553380 :   return *this;
    1037             : }
    1038             : 
    1039      489072 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(ToBooleanMode mode,
    1040             :                                                        BytecodeLabel* label) {
    1041             :   DCHECK(!label->is_bound());
    1042      489072 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
    1043             :     OutputJumpIfTrue(label, 0);
    1044             :   } else {
    1045             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
    1046             :     OutputJumpIfToBooleanTrue(label, 0);
    1047             :   }
    1048      489072 :   return *this;
    1049             : }
    1050             : 
    1051     1035985 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(ToBooleanMode mode,
    1052             :                                                         BytecodeLabel* label) {
    1053             :   DCHECK(!label->is_bound());
    1054     1035985 :   if (mode == ToBooleanMode::kAlreadyBoolean) {
    1055             :     OutputJumpIfFalse(label, 0);
    1056             :   } else {
    1057             :     DCHECK_EQ(mode, ToBooleanMode::kConvertToBoolean);
    1058             :     OutputJumpIfToBooleanFalse(label, 0);
    1059             :   }
    1060     1035985 :   return *this;
    1061             : }
    1062             : 
    1063       12992 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
    1064             :   DCHECK(!label->is_bound());
    1065             :   OutputJumpIfNull(label, 0);
    1066       12992 :   return *this;
    1067             : }
    1068             : 
    1069       16810 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotNull(
    1070             :     BytecodeLabel* label) {
    1071             :   DCHECK(!label->is_bound());
    1072             :   OutputJumpIfNotNull(label, 0);
    1073       16810 :   return *this;
    1074             : }
    1075             : 
    1076       59082 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
    1077             :     BytecodeLabel* label) {
    1078             :   DCHECK(!label->is_bound());
    1079             :   OutputJumpIfUndefined(label, 0);
    1080       59082 :   return *this;
    1081             : }
    1082             : 
    1083       32155 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotUndefined(
    1084             :     BytecodeLabel* label) {
    1085             :   DCHECK(!label->is_bound());
    1086             :   OutputJumpIfNotUndefined(label, 0);
    1087       32155 :   return *this;
    1088             : }
    1089             : 
    1090       44023 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNil(BytecodeLabel* label,
    1091             :                                                       Token::Value op,
    1092             :                                                       NilValue nil) {
    1093       44023 :   if (op == Token::EQ) {
    1094             :     // TODO(rmcilroy): Implement JumpIfUndetectable.
    1095         573 :     return CompareUndetectable().JumpIfTrue(ToBooleanMode::kAlreadyBoolean,
    1096         573 :                                             label);
    1097             :   } else {
    1098             :     DCHECK_EQ(Token::EQ_STRICT, op);
    1099       43450 :     if (nil == kUndefinedValue) {
    1100       37591 :       return JumpIfUndefined(label);
    1101             :     } else {
    1102             :       DCHECK_EQ(kNullValue, nil);
    1103        5859 :       return JumpIfNull(label);
    1104             :     }
    1105             :   }
    1106             : }
    1107             : 
    1108       78567 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotNil(BytecodeLabel* label,
    1109             :                                                          Token::Value op,
    1110             :                                                          NilValue nil) {
    1111       78567 :   if (op == Token::EQ) {
    1112             :     // TODO(rmcilroy): Implement JumpIfUndetectable.
    1113       29606 :     return CompareUndetectable().JumpIfFalse(ToBooleanMode::kAlreadyBoolean,
    1114       29606 :                                              label);
    1115             :   } else {
    1116             :     DCHECK_EQ(Token::EQ_STRICT, op);
    1117       48961 :     if (nil == kUndefinedValue) {
    1118       32153 :       return JumpIfNotUndefined(label);
    1119             :     } else {
    1120             :       DCHECK_EQ(kNullValue, nil);
    1121       16808 :       return JumpIfNotNull(label);
    1122             :     }
    1123             :   }
    1124             : }
    1125             : 
    1126       27209 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfJSReceiver(
    1127             :     BytecodeLabel* label) {
    1128             :   DCHECK(!label->is_bound());
    1129             :   OutputJumpIfJSReceiver(label, 0);
    1130       27209 :   return *this;
    1131             : }
    1132             : 
    1133      222935 : BytecodeArrayBuilder& BytecodeArrayBuilder::JumpLoop(BytecodeLabel* label,
    1134             :                                                      int loop_depth) {
    1135             :   DCHECK(label->is_bound());
    1136             :   OutputJumpLoop(label, 0, loop_depth);
    1137      222935 :   return *this;
    1138             : }
    1139             : 
    1140       28694 : BytecodeArrayBuilder& BytecodeArrayBuilder::SwitchOnSmiNoFeedback(
    1141             :     BytecodeJumpTable* jump_table) {
    1142             :   OutputSwitchOnSmiNoFeedback(jump_table);
    1143       28694 :   return *this;
    1144             : }
    1145             : 
    1146     2354340 : BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
    1147     2354340 :   if (position != kNoSourcePosition) {
    1148             :     // We need to attach a non-breakable source position to a stack
    1149             :     // check, so we simply add it as expression position. There can be
    1150             :     // a prior statement position from constructs like:
    1151             :     //
    1152             :     //    do var x;  while (false);
    1153             :     //
    1154             :     // A Nop could be inserted for empty statements, but since no code
    1155             :     // is associated with these positions, instead we force the stack
    1156             :     // check's expression position which eliminates the empty
    1157             :     // statement's position.
    1158             :     latest_source_info_.ForceExpressionPosition(position);
    1159             :   }
    1160             :   OutputStackCheck();
    1161     2354342 :   return *this;
    1162             : }
    1163             : 
    1164      150350 : BytecodeArrayBuilder& BytecodeArrayBuilder::SetPendingMessage() {
    1165             :   OutputSetPendingMessage();
    1166      150350 :   return *this;
    1167             : }
    1168             : 
    1169       79501 : BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
    1170             :   OutputThrow();
    1171       79501 :   return *this;
    1172             : }
    1173             : 
    1174       47029 : BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
    1175             :   OutputReThrow();
    1176       47029 :   return *this;
    1177             : }
    1178             : 
    1179        9373 : BytecodeArrayBuilder& BytecodeArrayBuilder::Abort(BailoutReason reason) {
    1180             :   OutputAbort(reason);
    1181        9373 :   return *this;
    1182             : }
    1183             : 
    1184     2629337 : BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
    1185             :   OutputReturn();
    1186     2629339 :   return_seen_in_block_ = true;
    1187     2629339 :   return *this;
    1188             : }
    1189             : 
    1190      209672 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowReferenceErrorIfHole(
    1191             :     const AstRawString* name) {
    1192             :   size_t entry = GetConstantPoolEntry(name);
    1193             :   OutputThrowReferenceErrorIfHole(entry);
    1194      209672 :   return *this;
    1195             : }
    1196             : 
    1197       16388 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperNotCalledIfHole() {
    1198             :   OutputThrowSuperNotCalledIfHole();
    1199       16388 :   return *this;
    1200             : }
    1201             : 
    1202        2116 : BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperAlreadyCalledIfNotHole() {
    1203             :   OutputThrowSuperAlreadyCalledIfNotHole();
    1204        2116 :   return *this;
    1205             : }
    1206             : 
    1207        7340 : BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
    1208             :   OutputDebugger();
    1209        7340 :   return *this;
    1210             : }
    1211             : 
    1212        2465 : BytecodeArrayBuilder& BytecodeArrayBuilder::IncBlockCounter(
    1213             :     int coverage_array_slot) {
    1214             :   OutputIncBlockCounter(coverage_array_slot);
    1215        2465 :   return *this;
    1216             : }
    1217             : 
    1218        6073 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInEnumerate(Register receiver) {
    1219             :   OutputForInEnumerate(receiver);
    1220        6073 :   return *this;
    1221             : }
    1222             : 
    1223        6081 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
    1224             :     RegisterList cache_info_triple, int feedback_slot) {
    1225             :   DCHECK_EQ(3, cache_info_triple.register_count());
    1226             :   OutputForInPrepare(cache_info_triple, feedback_slot);
    1227        6081 :   return *this;
    1228             : }
    1229             : 
    1230        6073 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInContinue(
    1231             :     Register index, Register cache_length) {
    1232             :   OutputForInContinue(index, cache_length);
    1233        6073 :   return *this;
    1234             : }
    1235             : 
    1236        6073 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
    1237             :     Register receiver, Register index, RegisterList cache_type_array_pair,
    1238             :     int feedback_slot) {
    1239             :   DCHECK_EQ(2, cache_type_array_pair.register_count());
    1240             :   OutputForInNext(receiver, index, cache_type_array_pair, feedback_slot);
    1241        6073 :   return *this;
    1242             : }
    1243             : 
    1244        6073 : BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
    1245             :   OutputForInStep(index);
    1246        6073 :   return *this;
    1247             : }
    1248             : 
    1249       34663 : BytecodeArrayBuilder& BytecodeArrayBuilder::StoreModuleVariable(int cell_index,
    1250             :                                                                 int depth) {
    1251             :   OutputStaModuleVariable(cell_index, depth);
    1252       34663 :   return *this;
    1253             : }
    1254             : 
    1255        1566 : BytecodeArrayBuilder& BytecodeArrayBuilder::LoadModuleVariable(int cell_index,
    1256             :                                                                int depth) {
    1257             :   OutputLdaModuleVariable(cell_index, depth);
    1258        1566 :   return *this;
    1259             : }
    1260             : 
    1261       20047 : BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
    1262             :     Register generator, RegisterList registers, int suspend_id) {
    1263             :   OutputSuspendGenerator(generator, registers, registers.register_count(),
    1264             :                          suspend_id);
    1265       20047 :   return *this;
    1266             : }
    1267             : 
    1268        8287 : BytecodeArrayBuilder& BytecodeArrayBuilder::RestoreGeneratorState(
    1269             :     Register generator) {
    1270             :   OutputRestoreGeneratorState(generator);
    1271        8287 :   return *this;
    1272             : }
    1273             : 
    1274       20047 : BytecodeArrayBuilder& BytecodeArrayBuilder::RestoreGeneratorRegisters(
    1275             :     Register generator, RegisterList registers) {
    1276             :   OutputRestoreGeneratorRegisters(generator, registers,
    1277             :                                   registers.register_count());
    1278       20047 :   return *this;
    1279             : }
    1280             : 
    1281      138435 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(
    1282             :     int handler_id, HandlerTable::CatchPrediction catch_prediction) {
    1283             :   BytecodeLabel handler;
    1284      138435 :   Bind(&handler);
    1285      138435 :   handler_table_builder()->SetHandlerTarget(handler_id, handler.offset());
    1286      138435 :   handler_table_builder()->SetPrediction(handler_id, catch_prediction);
    1287      138435 :   return *this;
    1288             : }
    1289             : 
    1290      138435 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
    1291             :                                                          Register context) {
    1292             :   BytecodeLabel try_begin;
    1293      138435 :   Bind(&try_begin);
    1294      138435 :   handler_table_builder()->SetTryRegionStart(handler_id, try_begin.offset());
    1295      138435 :   handler_table_builder()->SetContextRegister(handler_id, context);
    1296      138435 :   return *this;
    1297             : }
    1298             : 
    1299      138435 : BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
    1300             :   BytecodeLabel try_end;
    1301      138435 :   Bind(&try_end);
    1302      138435 :   handler_table_builder()->SetTryRegionEnd(handler_id, try_end.offset());
    1303      138435 :   return *this;
    1304             : }
    1305             : 
    1306      862646 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallProperty(Register callable,
    1307             :                                                          RegisterList args,
    1308             :                                                          int feedback_slot) {
    1309      862646 :   if (args.register_count() == 1) {
    1310             :     OutputCallProperty0(callable, args[0], feedback_slot);
    1311      700411 :   } else if (args.register_count() == 2) {
    1312             :     OutputCallProperty1(callable, args[0], args[1], feedback_slot);
    1313      189445 :   } else if (args.register_count() == 3) {
    1314             :     OutputCallProperty2(callable, args[0], args[1], args[2], feedback_slot);
    1315             :   } else {
    1316             :     OutputCallProperty(callable, args, args.register_count(), feedback_slot);
    1317             :   }
    1318      862646 :   return *this;
    1319             : }
    1320             : 
    1321     1823479 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallUndefinedReceiver(
    1322             :     Register callable, RegisterList args, int feedback_slot) {
    1323     1823479 :   if (args.register_count() == 0) {
    1324             :     OutputCallUndefinedReceiver0(callable, feedback_slot);
    1325     1643751 :   } else if (args.register_count() == 1) {
    1326             :     OutputCallUndefinedReceiver1(callable, args[0], feedback_slot);
    1327      994882 :   } else if (args.register_count() == 2) {
    1328             :     OutputCallUndefinedReceiver2(callable, args[0], args[1], feedback_slot);
    1329             :   } else {
    1330             :     OutputCallUndefinedReceiver(callable, args, args.register_count(),
    1331             :                                 feedback_slot);
    1332             :   }
    1333     1823481 :   return *this;
    1334             : }
    1335             : 
    1336        2525 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallAnyReceiver(Register callable,
    1337             :                                                             RegisterList args,
    1338             :                                                             int feedback_slot) {
    1339             :   OutputCallAnyReceiver(callable, args, args.register_count(), feedback_slot);
    1340        2525 :   return *this;
    1341             : }
    1342             : 
    1343        1492 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallWithSpread(Register callable,
    1344             :                                                            RegisterList args,
    1345             :                                                            int feedback_slot) {
    1346             :   OutputCallWithSpread(callable, args, args.register_count(), feedback_slot);
    1347        1492 :   return *this;
    1348             : }
    1349             : 
    1350      157028 : BytecodeArrayBuilder& BytecodeArrayBuilder::Construct(Register constructor,
    1351             :                                                       RegisterList args,
    1352             :                                                       int feedback_slot_id) {
    1353             :   OutputConstruct(constructor, args, args.register_count(), feedback_slot_id);
    1354      157028 :   return *this;
    1355             : }
    1356             : 
    1357        2972 : BytecodeArrayBuilder& BytecodeArrayBuilder::ConstructWithSpread(
    1358             :     Register constructor, RegisterList args, int feedback_slot_id) {
    1359             :   OutputConstructWithSpread(constructor, args, args.register_count(),
    1360             :                             feedback_slot_id);
    1361        2972 :   return *this;
    1362             : }
    1363             : 
    1364     1216124 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1365             :     Runtime::FunctionId function_id, RegisterList args) {
    1366             :   DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
    1367             :   DCHECK_LE(Bytecodes::SizeForUnsignedOperand(function_id),
    1368             :             OperandSize::kShort);
    1369     1216124 :   if (IntrinsicsHelper::IsSupported(function_id)) {
    1370             :     IntrinsicsHelper::IntrinsicId intrinsic_id =
    1371      259220 :         IntrinsicsHelper::FromRuntimeId(function_id);
    1372             :     OutputInvokeIntrinsic(static_cast<int>(intrinsic_id), args,
    1373             :                           args.register_count());
    1374             :   } else {
    1375             :     OutputCallRuntime(static_cast<int>(function_id), args,
    1376             :                       args.register_count());
    1377             :   }
    1378     1216124 :   return *this;
    1379             : }
    1380             : 
    1381      446140 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1382             :     Runtime::FunctionId function_id, Register arg) {
    1383      446140 :   return CallRuntime(function_id, RegisterList(arg.index(), 1));
    1384             : }
    1385             : 
    1386       61440 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
    1387             :     Runtime::FunctionId function_id) {
    1388       61440 :   return CallRuntime(function_id, RegisterList());
    1389             : }
    1390             : 
    1391        2150 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
    1392             :     Runtime::FunctionId function_id, RegisterList args,
    1393             :     RegisterList return_pair) {
    1394             :   DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
    1395             :   DCHECK_LE(Bytecodes::SizeForUnsignedOperand(function_id),
    1396             :             OperandSize::kShort);
    1397             :   DCHECK_EQ(2, return_pair.register_count());
    1398             :   OutputCallRuntimeForPair(static_cast<uint16_t>(function_id), args,
    1399        2150 :                            args.register_count(), return_pair);
    1400        2150 :   return *this;
    1401             : }
    1402             : 
    1403        2149 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
    1404             :     Runtime::FunctionId function_id, Register arg, RegisterList return_pair) {
    1405             :   return CallRuntimeForPair(function_id, RegisterList(arg.index(), 1),
    1406        2149 :                             return_pair);
    1407             : }
    1408             : 
    1409       90349 : BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
    1410             :                                                           RegisterList args) {
    1411             :   OutputCallJSRuntime(context_index, args, args.register_count());
    1412       90349 :   return *this;
    1413             : }
    1414             : 
    1415        9508 : BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
    1416             :                                                    LanguageMode language_mode) {
    1417        9508 :   if (language_mode == LanguageMode::kSloppy) {
    1418             :     OutputDeletePropertySloppy(object);
    1419             :   } else {
    1420             :     DCHECK_EQ(language_mode, LanguageMode::kStrict);
    1421             :     OutputDeletePropertyStrict(object);
    1422             :   }
    1423        9508 :   return *this;
    1424             : }
    1425             : 
    1426           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(
    1427             :     const AstRawString* raw_string) {
    1428    12120282 :   return constant_array_builder()->Insert(raw_string);
    1429             : }
    1430             : 
    1431           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(const AstValue* heap_number) {
    1432             :   DCHECK(heap_number->IsHeapNumber() || heap_number->IsBigInt());
    1433      726438 :   return constant_array_builder()->Insert(heap_number);
    1434             : }
    1435             : 
    1436           0 : size_t BytecodeArrayBuilder::GetConstantPoolEntry(const Scope* scope) {
    1437      170339 :   return constant_array_builder()->Insert(scope);
    1438             : }
    1439             : 
    1440             : #define ENTRY_GETTER(NAME, ...)                            \
    1441             :   size_t BytecodeArrayBuilder::NAME##ConstantPoolEntry() { \
    1442             :     return constant_array_builder()->Insert##NAME();       \
    1443             :   }
    1444      155721 : SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER)
    1445             : #undef ENTRY_GETTER
    1446             : 
    1447       28694 : BytecodeJumpTable* BytecodeArrayBuilder::AllocateJumpTable(
    1448       28694 :     int size, int case_value_base) {
    1449             :   DCHECK_GT(size, 0);
    1450             : 
    1451       28694 :   size_t constant_pool_index = constant_array_builder()->InsertJumpTable(size);
    1452             : 
    1453             :   return new (zone())
    1454       28694 :       BytecodeJumpTable(constant_pool_index, size, case_value_base, zone());
    1455             : }
    1456             : 
    1457     4428508 : size_t BytecodeArrayBuilder::AllocateDeferredConstantPoolEntry() {
    1458     4428508 :   return constant_array_builder()->InsertDeferred();
    1459             : }
    1460             : 
    1461     4428506 : void BytecodeArrayBuilder::SetDeferredConstantPoolEntry(size_t entry,
    1462             :                                                         Handle<Object> object) {
    1463     4428506 :   constant_array_builder()->SetDeferredAt(entry, object);
    1464     4428506 : }
    1465             : 
    1466           0 : bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
    1467           0 :   if (!reg.is_valid()) {
    1468             :     return false;
    1469             :   }
    1470             : 
    1471           0 :   if (reg.is_current_context() || reg.is_function_closure()) {
    1472             :     return true;
    1473           0 :   } else if (reg.is_parameter()) {
    1474           0 :     int parameter_index = reg.ToParameterIndex(parameter_count());
    1475           0 :     return parameter_index >= 0 && parameter_index < parameter_count();
    1476           0 :   } else if (reg.index() < fixed_register_count()) {
    1477             :     return true;
    1478             :   } else {
    1479           0 :     return register_allocator()->RegisterIsLive(reg);
    1480             :   }
    1481             : }
    1482             : 
    1483           0 : bool BytecodeArrayBuilder::RegisterListIsValid(RegisterList reg_list) const {
    1484           0 :   if (reg_list.register_count() == 0) {
    1485             :     return reg_list.first_register() == Register(0);
    1486             :   } else {
    1487             :     int first_reg_index = reg_list.first_register().index();
    1488           0 :     for (int i = 0; i < reg_list.register_count(); i++) {
    1489           0 :       if (!RegisterIsValid(Register(first_reg_index + i))) {
    1490             :         return false;
    1491             :       }
    1492             :     }
    1493             :     return true;
    1494             :   }
    1495             : }
    1496             : 
    1497             : template <Bytecode bytecode, AccumulatorUse accumulator_use>
    1498    47354987 : void BytecodeArrayBuilder::PrepareToOutputBytecode() {
    1499    47354987 :   if (register_optimizer_)
    1500             :     register_optimizer_->PrepareForBytecode<bytecode, accumulator_use>();
    1501    47354996 : }
    1502             : 
    1503    16200244 : uint32_t BytecodeArrayBuilder::GetInputRegisterOperand(Register reg) {
    1504             :   DCHECK(RegisterIsValid(reg));
    1505    16200244 :   if (register_optimizer_) reg = register_optimizer_->GetInputRegister(reg);
    1506    16200245 :   return static_cast<uint32_t>(reg.ToOperand());
    1507             : }
    1508             : 
    1509      634853 : uint32_t BytecodeArrayBuilder::GetOutputRegisterOperand(Register reg) {
    1510             :   DCHECK(RegisterIsValid(reg));
    1511      634853 :   if (register_optimizer_) register_optimizer_->PrepareOutputRegister(reg);
    1512      634853 :   return static_cast<uint32_t>(reg.ToOperand());
    1513             : }
    1514             : 
    1515     1812308 : uint32_t BytecodeArrayBuilder::GetInputRegisterListOperand(
    1516             :     RegisterList reg_list) {
    1517             :   DCHECK(RegisterListIsValid(reg_list));
    1518     1812308 :   if (register_optimizer_)
    1519     1811515 :     reg_list = register_optimizer_->GetInputRegisterList(reg_list);
    1520     1812308 :   return static_cast<uint32_t>(reg_list.first_register().ToOperand());
    1521             : }
    1522             : 
    1523       28278 : uint32_t BytecodeArrayBuilder::GetOutputRegisterListOperand(
    1524             :     RegisterList reg_list) {
    1525             :   DCHECK(RegisterListIsValid(reg_list));
    1526       28278 :   if (register_optimizer_)
    1527       28278 :     register_optimizer_->PrepareOutputRegisterList(reg_list);
    1528       28278 :   return static_cast<uint32_t>(reg_list.first_register().ToOperand());
    1529             : }
    1530             : 
    1531           0 : std::ostream& operator<<(std::ostream& os,
    1532             :                          const BytecodeArrayBuilder::ToBooleanMode& mode) {
    1533           0 :   switch (mode) {
    1534             :     case BytecodeArrayBuilder::ToBooleanMode::kAlreadyBoolean:
    1535           0 :       return os << "AlreadyBoolean";
    1536             :     case BytecodeArrayBuilder::ToBooleanMode::kConvertToBoolean:
    1537           0 :       return os << "ConvertToBoolean";
    1538             :   }
    1539           0 :   UNREACHABLE();
    1540             : }
    1541             : 
    1542             : }  // namespace interpreter
    1543             : }  // namespace internal
    1544             : }  // namespace v8

Generated by: LCOV version 1.10