LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-array-writer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 171 185 92.4 %
Date: 2019-02-19 Functions: 18 22 81.8 %

          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-writer.h"
       6             : 
       7             : #include "src/api-inl.h"
       8             : #include "src/interpreter/bytecode-jump-table.h"
       9             : #include "src/interpreter/bytecode-label.h"
      10             : #include "src/interpreter/bytecode-node.h"
      11             : #include "src/interpreter/bytecode-register.h"
      12             : #include "src/interpreter/bytecode-source-info.h"
      13             : #include "src/interpreter/constant-array-builder.h"
      14             : #include "src/log.h"
      15             : #include "src/objects-inl.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace interpreter {
      20             : 
      21             : STATIC_CONST_MEMBER_DEFINITION const size_t
      22             :     BytecodeArrayWriter::kMaxSizeOfPackedBytecode;
      23             : 
      24     2107289 : BytecodeArrayWriter::BytecodeArrayWriter(
      25             :     Zone* zone, ConstantArrayBuilder* constant_array_builder,
      26             :     SourcePositionTableBuilder::RecordingMode source_position_mode)
      27             :     : bytecodes_(zone),
      28             :       unbound_jumps_(0),
      29             :       source_position_table_builder_(source_position_mode),
      30             :       constant_array_builder_(constant_array_builder),
      31             :       last_bytecode_(Bytecode::kIllegal),
      32             :       last_bytecode_offset_(0),
      33             :       last_bytecode_had_source_info_(false),
      34             :       elide_noneffectful_bytecodes_(FLAG_ignition_elide_noneffectful_bytecodes),
      35     4214578 :       exit_seen_in_block_(false) {
      36     2107292 :   bytecodes_.reserve(512);  // Derived via experimentation.
      37     2107291 : }
      38             : 
      39     2082970 : Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
      40     2082954 :     Isolate* isolate, int register_count, int parameter_count,
      41     2082970 :     Handle<ByteArray> handler_table) {
      42             :   DCHECK_EQ(0, unbound_jumps_);
      43             : 
      44     4165940 :   int bytecode_size = static_cast<int>(bytecodes()->size());
      45     2082970 :   int frame_size = register_count * kSystemPointerSize;
      46             :   Handle<FixedArray> constant_pool =
      47     2082970 :       constant_array_builder()->ToFixedArray(isolate);
      48             :   Handle<BytecodeArray> bytecode_array = isolate->factory()->NewBytecodeArray(
      49             :       bytecode_size, &bytecodes()->front(), frame_size, parameter_count,
      50     2082977 :       constant_pool);
      51     2082975 :   bytecode_array->set_handler_table(*handler_table);
      52             :   // TODO(v8:8510): Need to support native functions that should always have
      53             :   // source positions suppressed and should write empty_byte_array here.
      54     2082978 :   if (!source_position_table_builder_.Omit()) {
      55             :     Handle<ByteArray> source_position_table =
      56     2082958 :         source_position_table_builder()->ToSourcePositionTable(isolate);
      57     4165912 :     bytecode_array->set_source_position_table(*source_position_table);
      58     2083260 :     LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(
      59             :                                 bytecode_array->GetFirstBytecodeAddress(),
      60             :                                 *source_position_table));
      61             :   }
      62     2082977 :   return bytecode_array;
      63             : }
      64             : 
      65   228877530 : void BytecodeArrayWriter::Write(BytecodeNode* node) {
      66             :   DCHECK(!Bytecodes::IsJump(node->bytecode()));
      67             : 
      68   152884524 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      69             :   UpdateExitSeenInBlock(node->bytecode());
      70   228659178 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      71             : 
      72    76230190 :   UpdateSourcePositionTable(node);
      73    76234137 :   EmitBytecode(node);
      74             : }
      75             : 
      76     6189050 : void BytecodeArrayWriter::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
      77             :   DCHECK(Bytecodes::IsJump(node->bytecode()));
      78             : 
      79             :   // TODO(rmcilroy): For forward jumps we could also mark the label as dead,
      80             :   // thereby avoiding emitting dead code when we bind the label.
      81     4140956 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      82             :   UpdateExitSeenInBlock(node->bytecode());
      83     6177897 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      84             : 
      85     2059341 :   UpdateSourcePositionTable(node);
      86     2059355 :   EmitJump(node, label);
      87             : }
      88             : 
      89       60036 : void BytecodeArrayWriter::WriteSwitch(BytecodeNode* node,
      90             :                                       BytecodeJumpTable* jump_table) {
      91             :   DCHECK(Bytecodes::IsSwitch(node->bytecode()));
      92             : 
      93             :   // TODO(rmcilroy): For jump tables we could also mark the table as dead,
      94             :   // thereby avoiding emitting dead code when we bind the entries.
      95       40516 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      96             :   UpdateExitSeenInBlock(node->bytecode());
      97       59667 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      98             : 
      99       19889 :   UpdateSourcePositionTable(node);
     100             :   EmitSwitch(node, jump_table);
     101             : }
     102             : 
     103     2665206 : void BytecodeArrayWriter::BindLabel(BytecodeLabel* label) {
     104     2665206 :   size_t current_offset = bytecodes()->size();
     105     2665206 :   if (label->is_forward_target()) {
     106             :     // An earlier jump instruction refers to this label. Update it's location.
     107     1806252 :     PatchJump(current_offset, label->offset());
     108             :     // Now treat as if the label will only be back referred to.
     109             :   }
     110             :   label->bind_to(current_offset);
     111             :   InvalidateLastBytecode();
     112     2665194 :   exit_seen_in_block_ = false;  // Starting a new basic block.
     113     2665194 : }
     114             : 
     115           0 : void BytecodeArrayWriter::BindLabel(const BytecodeLabel& target,
     116             :                                     BytecodeLabel* label) {
     117             :   DCHECK(!label->is_bound());
     118             :   DCHECK(target.is_bound());
     119           0 :   if (label->is_forward_target()) {
     120             :     // An earlier jump instruction refers to this label. Update it's location.
     121           0 :     PatchJump(target.offset(), label->offset());
     122             :     // Now treat as if the label will only be back referred to.
     123             :   }
     124             :   label->bind_to(target.offset());
     125             :   InvalidateLastBytecode();
     126             :   // exit_seen_in_block_ was reset when target was bound, so shouldn't be
     127             :   // changed here.
     128           0 : }
     129             : 
     130      140757 : void BytecodeArrayWriter::BindJumpTableEntry(BytecodeJumpTable* jump_table,
     131       46919 :                                              int case_value) {
     132             :   DCHECK(!jump_table->is_bound(case_value));
     133             : 
     134       46919 :   size_t current_offset = bytecodes()->size();
     135       46919 :   size_t relative_jump = current_offset - jump_table->switch_bytecode_offset();
     136             : 
     137             :   constant_array_builder()->SetJumpTableSmi(
     138             :       jump_table->ConstantPoolEntryFor(case_value),
     139       93838 :       Smi::FromInt(static_cast<int>(relative_jump)));
     140             :   jump_table->mark_bound(case_value);
     141             : 
     142             :   InvalidateLastBytecode();
     143       46919 :   exit_seen_in_block_ = false;  // Starting a new basic block.
     144       46919 : }
     145             : 
     146    78308238 : void BytecodeArrayWriter::UpdateSourcePositionTable(
     147             :     const BytecodeNode* const node) {
     148   156616476 :   int bytecode_offset = static_cast<int>(bytecodes()->size());
     149   109748144 :   const BytecodeSourceInfo& source_info = node->source_info();
     150    78308238 :   if (source_info.is_valid()) {
     151             :     source_position_table_builder()->AddPosition(
     152             :         bytecode_offset, SourcePosition(source_info.source_position()),
     153    62879812 :         source_info.is_statement());
     154             :   }
     155    78308090 : }
     156             : 
     157           0 : void BytecodeArrayWriter::UpdateExitSeenInBlock(Bytecode bytecode) {
     158             :   switch (bytecode) {
     159             :     case Bytecode::kReturn:
     160             :     case Bytecode::kThrow:
     161             :     case Bytecode::kReThrow:
     162             :     case Bytecode::kAbort:
     163             :     case Bytecode::kJump:
     164             :     case Bytecode::kJumpConstant:
     165             :     case Bytecode::kSuspendGenerator:
     166     2931581 :       exit_seen_in_block_ = true;
     167           0 :       break;
     168             :     default:
     169             :       break;
     170             :   }
     171           0 : }
     172             : 
     173    78298554 : void BytecodeArrayWriter::MaybeElideLastBytecode(Bytecode next_bytecode,
     174             :                                                  bool has_source_info) {
     175   156607092 :   if (!elide_noneffectful_bytecodes_) return;
     176             : 
     177             :   // If the last bytecode loaded the accumulator without any external effect,
     178             :   // and the next bytecode clobbers this load without reading the accumulator,
     179             :   // then the previous bytecode can be elided as it has no effect.
     180   175157637 :   if (Bytecodes::IsAccumulatorLoadWithoutEffects(last_bytecode_) &&
     181    78639793 :       Bytecodes::GetAccumulatorUse(next_bytecode) == AccumulatorUse::kWrite &&
     182      332505 :       (!last_bytecode_had_source_info_ || !has_source_info)) {
     183             :     DCHECK_GT(bytecodes()->size(), last_bytecode_offset_);
     184      329568 :     bytecodes()->resize(last_bytecode_offset_);
     185             :     // If the last bytecode had source info we will transfer the source info
     186             :     // to this bytecode.
     187      329568 :     has_source_info |= last_bytecode_had_source_info_;
     188             :   }
     189    78308867 :   last_bytecode_ = next_bytecode;
     190    78308867 :   last_bytecode_had_source_info_ = has_source_info;
     191   156617734 :   last_bytecode_offset_ = bytecodes()->size();
     192             : }
     193             : 
     194           0 : void BytecodeArrayWriter::InvalidateLastBytecode() {
     195     2712113 :   last_bytecode_ = Bytecode::kIllegal;
     196           0 : }
     197             : 
     198   156625602 : void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) {
     199             :   DCHECK_NE(node->bytecode(), Bytecode::kIllegal);
     200             : 
     201             :   Bytecode bytecode = node->bytecode();
     202             :   OperandScale operand_scale = node->operand_scale();
     203             : 
     204    78313991 :   if (operand_scale != OperandScale::kSingle) {
     205    12119313 :     Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale);
     206    24238861 :     bytecodes()->push_back(Bytecodes::ToByte(prefix));
     207             :   }
     208   156625759 :   bytecodes()->push_back(Bytecodes::ToByte(bytecode));
     209             : 
     210    78311611 :   const uint32_t* const operands = node->operands();
     211             :   const int operand_count = node->operand_count();
     212             :   const OperandSize* operand_sizes =
     213             :       Bytecodes::GetOperandSizes(bytecode, operand_scale);
     214   183840299 :   for (int i = 0; i < operand_count; ++i) {
     215   105533589 :     switch (operand_sizes[i]) {
     216             :       case OperandSize::kNone:
     217           0 :         UNREACHABLE();
     218             :         break;
     219             :       case OperandSize::kByte:
     220   168468461 :         bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
     221    84231754 :         break;
     222             :       case OperandSize::kShort: {
     223    11223213 :         uint16_t operand = static_cast<uint16_t>(operands[i]);
     224             :         const uint8_t* raw_operand = reinterpret_cast<const uint8_t*>(&operand);
     225    11223213 :         bytecodes()->push_back(raw_operand[0]);
     226    11223261 :         bytecodes()->push_back(raw_operand[1]);
     227             :         break;
     228             :       }
     229             :       case OperandSize::kQuad: {
     230             :         const uint8_t* raw_operand =
     231    10078252 :             reinterpret_cast<const uint8_t*>(&operands[i]);
     232    10078252 :         bytecodes()->push_back(raw_operand[0]);
     233    10078252 :         bytecodes()->push_back(raw_operand[1]);
     234    10078249 :         bytecodes()->push_back(raw_operand[2]);
     235    10078250 :         bytecodes()->push_back(raw_operand[3]);
     236    10078250 :         break;
     237             :       }
     238             :     }
     239             :   }
     240    78306710 : }
     241             : 
     242             : // static
     243       22999 : Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) {
     244       22999 :   switch (jump_bytecode) {
     245             :     case Bytecode::kJump:
     246             :       return Bytecode::kJumpConstant;
     247             :     case Bytecode::kJumpIfTrue:
     248        8729 :       return Bytecode::kJumpIfTrueConstant;
     249             :     case Bytecode::kJumpIfFalse:
     250        3912 :       return Bytecode::kJumpIfFalseConstant;
     251             :     case Bytecode::kJumpIfToBooleanTrue:
     252        4981 :       return Bytecode::kJumpIfToBooleanTrueConstant;
     253             :     case Bytecode::kJumpIfToBooleanFalse:
     254         104 :       return Bytecode::kJumpIfToBooleanFalseConstant;
     255             :     case Bytecode::kJumpIfNull:
     256         209 :       return Bytecode::kJumpIfNullConstant;
     257             :     case Bytecode::kJumpIfNotNull:
     258           1 :       return Bytecode::kJumpIfNotNullConstant;
     259             :     case Bytecode::kJumpIfUndefined:
     260         355 :       return Bytecode::kJumpIfUndefinedConstant;
     261             :     case Bytecode::kJumpIfNotUndefined:
     262          11 :       return Bytecode::kJumpIfNotUndefinedConstant;
     263             :     case Bytecode::kJumpIfJSReceiver:
     264           1 :       return Bytecode::kJumpIfJSReceiverConstant;
     265             :     default:
     266           0 :       UNREACHABLE();
     267             :   }
     268             : }
     269             : 
     270     1790274 : void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location,
     271     1790274 :                                                    int delta) {
     272     1790274 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     273             :   DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
     274             :   DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
     275             :   DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
     276             :   DCHECK_GT(delta, 0);
     277     1790274 :   size_t operand_location = jump_location + 1;
     278             :   DCHECK_EQ(bytecodes()->at(operand_location), k8BitJumpPlaceholder);
     279     3580548 :   if (Bytecodes::ScaleForUnsignedOperand(delta) == OperandScale::kSingle) {
     280             :     // The jump fits within the range of an UImm8 operand, so cancel
     281             :     // the reservation and jump directly.
     282     1767282 :     constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
     283     1767305 :     bytecodes()->at(operand_location) = static_cast<uint8_t>(delta);
     284             :   } else {
     285             :     // The jump does not fit within the range of an UImm8 operand, so
     286             :     // commit reservation putting the offset into the constant pool,
     287             :     // and update the jump instruction and operand.
     288             :     size_t entry = constant_array_builder()->CommitReservedEntry(
     289       22992 :         OperandSize::kByte, Smi::FromInt(delta));
     290             :     DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<uint32_t>(entry)),
     291             :               OperandSize::kByte);
     292       22994 :     jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
     293       22994 :     bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
     294       22994 :     bytecodes()->at(operand_location) = static_cast<uint8_t>(entry);
     295             :   }
     296     1790299 : }
     297             : 
     298       15948 : void BytecodeArrayWriter::PatchJumpWith16BitOperand(size_t jump_location,
     299       15948 :                                                     int delta) {
     300       15948 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     301             :   DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
     302             :   DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
     303             :   DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
     304             :   DCHECK_GT(delta, 0);
     305       15948 :   size_t operand_location = jump_location + 1;
     306             :   uint8_t operand_bytes[2];
     307       31896 :   if (Bytecodes::ScaleForUnsignedOperand(delta) <= OperandScale::kDouble) {
     308             :     // The jump fits within the range of an Imm16 operand, so cancel
     309             :     // the reservation and jump directly.
     310       15943 :     constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
     311             :     WriteUnalignedUInt16(reinterpret_cast<Address>(operand_bytes),
     312       15943 :                          static_cast<uint16_t>(delta));
     313             :   } else {
     314             :     // The jump does not fit within the range of an Imm16 operand, so
     315             :     // commit reservation putting the offset into the constant pool,
     316             :     // and update the jump instruction and operand.
     317             :     size_t entry = constant_array_builder()->CommitReservedEntry(
     318           5 :         OperandSize::kShort, Smi::FromInt(delta));
     319           5 :     jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
     320           5 :     bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
     321             :     WriteUnalignedUInt16(reinterpret_cast<Address>(operand_bytes),
     322           5 :                          static_cast<uint16_t>(entry));
     323             :   }
     324             :   DCHECK(bytecodes()->at(operand_location) == k8BitJumpPlaceholder &&
     325             :          bytecodes()->at(operand_location + 1) == k8BitJumpPlaceholder);
     326       31896 :   bytecodes()->at(operand_location++) = operand_bytes[0];
     327       15948 :   bytecodes()->at(operand_location) = operand_bytes[1];
     328       15948 : }
     329             : 
     330           5 : void BytecodeArrayWriter::PatchJumpWith32BitOperand(size_t jump_location,
     331           5 :                                                     int delta) {
     332             :   DCHECK(Bytecodes::IsJumpImmediate(
     333             :       Bytecodes::FromByte(bytecodes()->at(jump_location))));
     334           5 :   constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad);
     335             :   uint8_t operand_bytes[4];
     336             :   WriteUnalignedUInt32(reinterpret_cast<Address>(operand_bytes),
     337           5 :                        static_cast<uint32_t>(delta));
     338           5 :   size_t operand_location = jump_location + 1;
     339             :   DCHECK(bytecodes()->at(operand_location) == k8BitJumpPlaceholder &&
     340             :          bytecodes()->at(operand_location + 1) == k8BitJumpPlaceholder &&
     341             :          bytecodes()->at(operand_location + 2) == k8BitJumpPlaceholder &&
     342             :          bytecodes()->at(operand_location + 3) == k8BitJumpPlaceholder);
     343          10 :   bytecodes()->at(operand_location++) = operand_bytes[0];
     344          10 :   bytecodes()->at(operand_location++) = operand_bytes[1];
     345          10 :   bytecodes()->at(operand_location++) = operand_bytes[2];
     346           5 :   bytecodes()->at(operand_location) = operand_bytes[3];
     347           5 : }
     348             : 
     349     1806233 : void BytecodeArrayWriter::PatchJump(size_t jump_target, size_t jump_location) {
     350     1806233 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     351     1806233 :   int delta = static_cast<int>(jump_target - jump_location);
     352             :   int prefix_offset = 0;
     353             :   OperandScale operand_scale = OperandScale::kSingle;
     354     1806233 :   if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) {
     355             :     // If a prefix scaling bytecode is emitted the target offset is one
     356             :     // less than the case of no prefix scaling bytecode.
     357       15953 :     delta -= 1;
     358             :     prefix_offset = 1;
     359       15953 :     operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode);
     360             :     jump_bytecode =
     361       15953 :         Bytecodes::FromByte(bytecodes()->at(jump_location + prefix_offset));
     362             :   }
     363             : 
     364             :   DCHECK(Bytecodes::IsJump(jump_bytecode));
     365     1806233 :   switch (operand_scale) {
     366             :     case OperandScale::kSingle:
     367     1790280 :       PatchJumpWith8BitOperand(jump_location, delta);
     368     1790299 :       break;
     369             :     case OperandScale::kDouble:
     370       15948 :       PatchJumpWith16BitOperand(jump_location + prefix_offset, delta);
     371       15948 :       break;
     372             :     case OperandScale::kQuadruple:
     373           5 :       PatchJumpWith32BitOperand(jump_location + prefix_offset, delta);
     374           5 :       break;
     375             :     default:
     376           0 :       UNREACHABLE();
     377             :   }
     378     1806252 :   unbound_jumps_--;
     379     1806252 : }
     380             : 
     381     6177969 : void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
     382             :   DCHECK(Bytecodes::IsJump(node->bytecode()));
     383             :   DCHECK_EQ(0u, node->operand(0));
     384             : 
     385     2059323 :   size_t current_offset = bytecodes()->size();
     386             : 
     387     2059323 :   if (label->is_bound()) {
     388      253077 :     CHECK_GE(current_offset, label->offset());
     389      253077 :     CHECK_LE(current_offset, static_cast<size_t>(kMaxUInt32));
     390             :     // Label has been bound already so this is a backwards jump.
     391      253077 :     uint32_t delta = static_cast<uint32_t>(current_offset - label->offset());
     392             :     OperandScale operand_scale = Bytecodes::ScaleForUnsignedOperand(delta);
     393      253077 :     if (operand_scale > OperandScale::kSingle) {
     394             :       // Adjust for scaling byte prefix for wide jump offset.
     395        8160 :       delta += 1;
     396             :     }
     397             :     DCHECK_EQ(Bytecode::kJumpLoop, node->bytecode());
     398      253077 :     node->update_operand0(delta);
     399             :   } else {
     400             :     // The label has not yet been bound so this is a forward reference
     401             :     // that will be patched when the label is bound. We create a
     402             :     // reservation in the constant pool so the jump can be patched
     403             :     // when the label is bound. The reservation means the maximum size
     404             :     // of the operand for the constant is known and the jump can
     405             :     // be emitted into the bytecode stream with space for the operand.
     406     1806246 :     unbound_jumps_++;
     407             :     label->set_referrer(current_offset);
     408             :     OperandSize reserved_operand_size =
     409     1806246 :         constant_array_builder()->CreateReservedEntry();
     410             :     DCHECK_NE(Bytecode::kJumpLoop, node->bytecode());
     411     1806246 :     switch (reserved_operand_size) {
     412             :       case OperandSize::kNone:
     413           0 :         UNREACHABLE();
     414             :         break;
     415             :       case OperandSize::kByte:
     416     1790308 :         node->update_operand0(k8BitJumpPlaceholder);
     417     1790331 :         break;
     418             :       case OperandSize::kShort:
     419       15948 :         node->update_operand0(k16BitJumpPlaceholder);
     420       15948 :         break;
     421             :       case OperandSize::kQuad:
     422           5 :         node->update_operand0(k32BitJumpPlaceholder);
     423           5 :         break;
     424             :     }
     425             :   }
     426     2059346 :   EmitBytecode(node);
     427     2059350 : }
     428             : 
     429       19889 : void BytecodeArrayWriter::EmitSwitch(BytecodeNode* node,
     430             :                                      BytecodeJumpTable* jump_table) {
     431             :   DCHECK(Bytecodes::IsSwitch(node->bytecode()));
     432             : 
     433       19889 :   size_t current_offset = bytecodes()->size();
     434       19889 :   if (node->operand_scale() > OperandScale::kSingle) {
     435             :     // Adjust for scaling byte prefix.
     436         122 :     current_offset += 1;
     437             :   }
     438             :   jump_table->set_switch_bytecode_offset(current_offset);
     439             : 
     440       19889 :   EmitBytecode(node);
     441           0 : }
     442             : 
     443             : }  // namespace interpreter
     444             : }  // namespace internal
     445      178779 : }  // namespace v8

Generated by: LCOV version 1.10