LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-array-writer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 174 187 93.0 %
Date: 2019-04-17 Functions: 23 27 85.2 %

          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/interpreter/handler-table-builder.h"
      15             : #include "src/log.h"
      16             : #include "src/objects-inl.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace interpreter {
      21             : 
      22             : STATIC_CONST_MEMBER_DEFINITION const size_t
      23             :     BytecodeArrayWriter::kMaxSizeOfPackedBytecode;
      24             : 
      25     2136485 : BytecodeArrayWriter::BytecodeArrayWriter(
      26             :     Zone* zone, ConstantArrayBuilder* constant_array_builder,
      27             :     SourcePositionTableBuilder::RecordingMode source_position_mode)
      28             :     : bytecodes_(zone),
      29             :       unbound_jumps_(0),
      30             :       source_position_table_builder_(source_position_mode),
      31             :       constant_array_builder_(constant_array_builder),
      32             :       last_bytecode_(Bytecode::kIllegal),
      33             :       last_bytecode_offset_(0),
      34             :       last_bytecode_had_source_info_(false),
      35             :       elide_noneffectful_bytecodes_(FLAG_ignition_elide_noneffectful_bytecodes),
      36     4272970 :       exit_seen_in_block_(false) {
      37     2136487 :   bytecodes_.reserve(512);  // Derived via experimentation.
      38     2136489 : }
      39             : 
      40     2111466 : Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
      41             :     Isolate* isolate, int register_count, int parameter_count,
      42             :     Handle<ByteArray> handler_table) {
      43             :   DCHECK_EQ(0, unbound_jumps_);
      44             : 
      45     2111466 :   int bytecode_size = static_cast<int>(bytecodes()->size());
      46     2111466 :   int frame_size = register_count * kSystemPointerSize;
      47             :   Handle<FixedArray> constant_pool =
      48     2111466 :       constant_array_builder()->ToFixedArray(isolate);
      49             :   Handle<BytecodeArray> bytecode_array = isolate->factory()->NewBytecodeArray(
      50             :       bytecode_size, &bytecodes()->front(), frame_size, parameter_count,
      51     2111484 :       constant_pool);
      52     2111498 :   bytecode_array->set_handler_table(*handler_table);
      53     2111500 :   if (!source_position_table_builder_.Lazy()) {
      54             :     Handle<ByteArray> source_position_table =
      55             :         source_position_table_builder_.Omit()
      56             :             ? ReadOnlyRoots(isolate).empty_byte_array_handle()
      57     4222896 :             : source_position_table_builder()->ToSourcePositionTable(isolate);
      58     4222874 :     bytecode_array->set_source_position_table(*source_position_table);
      59     2111748 :     LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(
      60             :                                 bytecode_array->GetFirstBytecodeAddress(),
      61             :                                 *source_position_table));
      62             :   }
      63     2111500 :   return bytecode_array;
      64             : }
      65             : 
      66    78166992 : void BytecodeArrayWriter::Write(BytecodeNode* node) {
      67             :   DCHECK(!Bytecodes::IsJump(node->bytecode()));
      68             : 
      69    78166992 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      70             :   UpdateExitSeenInBlock(node->bytecode());
      71    77943347 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      72             : 
      73    77944560 :   UpdateSourcePositionTable(node);
      74    77945972 :   EmitBytecode(node);
      75             : }
      76             : 
      77     1837935 : void BytecodeArrayWriter::WriteJump(BytecodeNode* node, BytecodeLabel* label) {
      78             :   DCHECK(Bytecodes::IsForwardJump(node->bytecode()));
      79             : 
      80     1837935 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      81             :   UpdateExitSeenInBlock(node->bytecode());
      82     1820864 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      83             : 
      84     1820870 :   UpdateSourcePositionTable(node);
      85     1820871 :   EmitJump(node, label);
      86             : }
      87             : 
      88      262328 : void BytecodeArrayWriter::WriteJumpLoop(BytecodeNode* node,
      89             :                                         BytecodeLoopHeader* loop_header) {
      90             :   DCHECK_EQ(node->bytecode(), Bytecode::kJumpLoop);
      91             : 
      92      262328 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
      93             :   UpdateExitSeenInBlock(node->bytecode());
      94      253907 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
      95             : 
      96      253905 :   UpdateSourcePositionTable(node);
      97      253909 :   EmitJumpLoop(node, loop_header);
      98             : }
      99             : 
     100       20229 : void BytecodeArrayWriter::WriteSwitch(BytecodeNode* node,
     101             :                                       BytecodeJumpTable* jump_table) {
     102             :   DCHECK(Bytecodes::IsSwitch(node->bytecode()));
     103             : 
     104       20229 :   if (exit_seen_in_block_) return;  // Don't emit dead code.
     105             :   UpdateExitSeenInBlock(node->bytecode());
     106       19844 :   MaybeElideLastBytecode(node->bytecode(), node->source_info().is_valid());
     107             : 
     108       19845 :   UpdateSourcePositionTable(node);
     109             :   EmitSwitch(node, jump_table);
     110             : }
     111             : 
     112     1820860 : void BytecodeArrayWriter::BindLabel(BytecodeLabel* label) {
     113             :   DCHECK(label->has_referrer_jump());
     114             :   size_t current_offset = bytecodes()->size();
     115             :   // Update the jump instruction's location.
     116     1820860 :   PatchJump(current_offset, label->jump_offset());
     117             :   label->bind();
     118             :   StartBasicBlock();
     119     1820855 : }
     120             : 
     121      262293 : void BytecodeArrayWriter::BindLoopHeader(BytecodeLoopHeader* loop_header) {
     122             :   size_t current_offset = bytecodes()->size();
     123             :   loop_header->bind_to(current_offset);
     124             :   StartBasicBlock();
     125      262293 : }
     126             : 
     127       46832 : void BytecodeArrayWriter::BindJumpTableEntry(BytecodeJumpTable* jump_table,
     128             :                                              int case_value) {
     129             :   DCHECK(!jump_table->is_bound(case_value));
     130             : 
     131             :   size_t current_offset = bytecodes()->size();
     132       46832 :   size_t relative_jump = current_offset - jump_table->switch_bytecode_offset();
     133             : 
     134       46832 :   constant_array_builder()->SetJumpTableSmi(
     135             :       jump_table->ConstantPoolEntryFor(case_value),
     136       46832 :       Smi::FromInt(static_cast<int>(relative_jump)));
     137             :   jump_table->mark_bound(case_value);
     138             : 
     139             :   StartBasicBlock();
     140       46832 : }
     141             : 
     142      154536 : void BytecodeArrayWriter::BindHandlerTarget(
     143             :     HandlerTableBuilder* handler_table_builder, int handler_id) {
     144             :   size_t current_offset = bytecodes()->size();
     145             :   StartBasicBlock();
     146      154536 :   handler_table_builder->SetHandlerTarget(handler_id, current_offset);
     147      154536 : }
     148             : 
     149      154538 : void BytecodeArrayWriter::BindTryRegionStart(
     150             :     HandlerTableBuilder* handler_table_builder, int handler_id) {
     151             :   size_t current_offset = bytecodes()->size();
     152             :   // Try blocks don't have to be in a separate basic block, but we do have to
     153             :   // invalidate the bytecode to avoid eliding it and changing the offset.
     154             :   InvalidateLastBytecode();
     155      154538 :   handler_table_builder->SetTryRegionStart(handler_id, current_offset);
     156      154539 : }
     157             : 
     158      154533 : void BytecodeArrayWriter::BindTryRegionEnd(
     159             :     HandlerTableBuilder* handler_table_builder, int handler_id) {
     160             :   // Try blocks don't have to be in a separate basic block, but we do have to
     161             :   // invalidate the bytecode to avoid eliding it and changing the offset.
     162             :   InvalidateLastBytecode();
     163             :   size_t current_offset = bytecodes()->size();
     164      154533 :   handler_table_builder->SetTryRegionEnd(handler_id, current_offset);
     165      154537 : }
     166             : 
     167           0 : void BytecodeArrayWriter::StartBasicBlock() {
     168             :   InvalidateLastBytecode();
     169     2284516 :   exit_seen_in_block_ = false;
     170           0 : }
     171             : 
     172    80038645 : void BytecodeArrayWriter::UpdateSourcePositionTable(
     173             :     const BytecodeNode* const node) {
     174    80038645 :   int bytecode_offset = static_cast<int>(bytecodes()->size());
     175             :   const BytecodeSourceInfo& source_info = node->source_info();
     176    80038645 :   if (source_info.is_valid()) {
     177    96308511 :     source_position_table_builder()->AddPosition(
     178             :         bytecode_offset, SourcePosition(source_info.source_position()),
     179    32102838 :         source_info.is_statement());
     180             :   }
     181    80038642 : }
     182             : 
     183           0 : void BytecodeArrayWriter::UpdateExitSeenInBlock(Bytecode bytecode) {
     184             :   switch (bytecode) {
     185             :     case Bytecode::kReturn:
     186             :     case Bytecode::kThrow:
     187             :     case Bytecode::kReThrow:
     188             :     case Bytecode::kAbort:
     189             :     case Bytecode::kJump:
     190             :     case Bytecode::kJumpConstant:
     191             :     case Bytecode::kSuspendGenerator:
     192     2952827 :       exit_seen_in_block_ = true;
     193           0 :       break;
     194             :     default:
     195             :       break;
     196             :   }
     197           0 : }
     198             : 
     199    80036726 : void BytecodeArrayWriter::MaybeElideLastBytecode(Bytecode next_bytecode,
     200             :                                                  bool has_source_info) {
     201    80036726 :   if (!elide_noneffectful_bytecodes_) return;
     202             : 
     203             :   // If the last bytecode loaded the accumulator without any external effect,
     204             :   // and the next bytecode clobbers this load without reading the accumulator,
     205             :   // then the previous bytecode can be elided as it has no effect.
     206   179072038 :   if (Bytecodes::IsAccumulatorLoadWithoutEffects(last_bytecode_) &&
     207    80369767 :       Bytecodes::GetAccumulatorUse(next_bytecode) == AccumulatorUse::kWrite &&
     208      332548 :       (!last_bytecode_had_source_info_ || !has_source_info)) {
     209             :     DCHECK_GT(bytecodes()->size(), last_bytecode_offset_);
     210      329606 :     bytecodes()->resize(last_bytecode_offset_);
     211             :     // If the last bytecode had source info we will transfer the source info
     212             :     // to this bytecode.
     213      329606 :     has_source_info |= last_bytecode_had_source_info_;
     214             :   }
     215    80038804 :   last_bytecode_ = next_bytecode;
     216    80038804 :   last_bytecode_had_source_info_ = has_source_info;
     217    80038804 :   last_bytecode_offset_ = bytecodes()->size();
     218             : }
     219             : 
     220           0 : void BytecodeArrayWriter::InvalidateLastBytecode() {
     221     2593587 :   last_bytecode_ = Bytecode::kIllegal;
     222           0 : }
     223             : 
     224    80039551 : void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) {
     225             :   DCHECK_NE(node->bytecode(), Bytecode::kIllegal);
     226             : 
     227             :   Bytecode bytecode = node->bytecode();
     228             :   OperandScale operand_scale = node->operand_scale();
     229             : 
     230    80039551 :   if (operand_scale != OperandScale::kSingle) {
     231             :     Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale);
     232    24491440 :     bytecodes()->push_back(Bytecodes::ToByte(prefix));
     233             :   }
     234   160075896 :   bytecodes()->push_back(Bytecodes::ToByte(bytecode));
     235             : 
     236             :   const uint32_t* const operands = node->operands();
     237             :   const int operand_count = node->operand_count();
     238             :   const OperandSize* operand_sizes =
     239             :       Bytecodes::GetOperandSizes(bytecode, operand_scale);
     240   295903967 :   for (int i = 0; i < operand_count; ++i) {
     241   107936018 :     switch (operand_sizes[i]) {
     242             :       case OperandSize::kNone:
     243           0 :         UNREACHABLE();
     244             :         break;
     245             :       case OperandSize::kByte:
     246   172991021 :         bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
     247    86494402 :         break;
     248             :       case OperandSize::kShort: {
     249    11359676 :         uint16_t operand = static_cast<uint16_t>(operands[i]);
     250             :         const uint8_t* raw_operand = reinterpret_cast<const uint8_t*>(&operand);
     251    11359676 :         bytecodes()->push_back(raw_operand[0]);
     252    11359701 :         bytecodes()->push_back(raw_operand[1]);
     253             :         break;
     254             :       }
     255             :       case OperandSize::kQuad: {
     256             :         const uint8_t* raw_operand =
     257    10081397 :             reinterpret_cast<const uint8_t*>(&operands[i]);
     258    10081397 :         bytecodes()->push_back(raw_operand[0]);
     259    10081398 :         bytecodes()->push_back(raw_operand[1]);
     260    10081398 :         bytecodes()->push_back(raw_operand[2]);
     261    10081398 :         bytecodes()->push_back(raw_operand[3]);
     262    10081398 :         break;
     263             :       }
     264             :     }
     265             :   }
     266    80034140 : }
     267             : 
     268             : // static
     269       24537 : Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) {
     270       24537 :   switch (jump_bytecode) {
     271             :     case Bytecode::kJump:
     272             :       return Bytecode::kJumpConstant;
     273             :     case Bytecode::kJumpIfTrue:
     274        8673 :       return Bytecode::kJumpIfTrueConstant;
     275             :     case Bytecode::kJumpIfFalse:
     276        5121 :       return Bytecode::kJumpIfFalseConstant;
     277             :     case Bytecode::kJumpIfToBooleanTrue:
     278        5215 :       return Bytecode::kJumpIfToBooleanTrueConstant;
     279             :     case Bytecode::kJumpIfToBooleanFalse:
     280         210 :       return Bytecode::kJumpIfToBooleanFalseConstant;
     281             :     case Bytecode::kJumpIfNull:
     282         210 :       return Bytecode::kJumpIfNullConstant;
     283             :     case Bytecode::kJumpIfNotNull:
     284           1 :       return Bytecode::kJumpIfNotNullConstant;
     285             :     case Bytecode::kJumpIfUndefined:
     286         355 :       return Bytecode::kJumpIfUndefinedConstant;
     287             :     case Bytecode::kJumpIfNotUndefined:
     288           1 :       return Bytecode::kJumpIfNotUndefinedConstant;
     289             :     case Bytecode::kJumpIfJSReceiver:
     290           1 :       return Bytecode::kJumpIfJSReceiverConstant;
     291             :     default:
     292           0 :       UNREACHABLE();
     293             :   }
     294             : }
     295             : 
     296     1804904 : void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location,
     297             :                                                    int delta) {
     298     1804904 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     299             :   DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
     300             :   DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
     301             :   DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
     302             :   DCHECK_GT(delta, 0);
     303     1804904 :   size_t operand_location = jump_location + 1;
     304             :   DCHECK_EQ(bytecodes()->at(operand_location), k8BitJumpPlaceholder);
     305     3609808 :   if (Bytecodes::ScaleForUnsignedOperand(delta) == OperandScale::kSingle) {
     306             :     // The jump fits within the range of an UImm8 operand, so cancel
     307             :     // the reservation and jump directly.
     308     1780372 :     constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
     309     1780380 :     bytecodes()->at(operand_location) = static_cast<uint8_t>(delta);
     310             :   } else {
     311             :     // The jump does not fit within the range of an UImm8 operand, so
     312             :     // commit reservation putting the offset into the constant pool,
     313             :     // and update the jump instruction and operand.
     314             :     size_t entry = constant_array_builder()->CommitReservedEntry(
     315       24532 :         OperandSize::kByte, Smi::FromInt(delta));
     316             :     DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<uint32_t>(entry)),
     317             :               OperandSize::kByte);
     318       24531 :     jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
     319       24529 :     bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
     320       24529 :     bytecodes()->at(operand_location) = static_cast<uint8_t>(entry);
     321             :   }
     322     1804909 : }
     323             : 
     324       15949 : void BytecodeArrayWriter::PatchJumpWith16BitOperand(size_t jump_location,
     325             :                                                     int delta) {
     326       15949 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     327             :   DCHECK(Bytecodes::IsForwardJump(jump_bytecode));
     328             :   DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
     329             :   DCHECK_EQ(Bytecodes::GetOperandType(jump_bytecode, 0), OperandType::kUImm);
     330             :   DCHECK_GT(delta, 0);
     331       15949 :   size_t operand_location = jump_location + 1;
     332             :   uint8_t operand_bytes[2];
     333       31898 :   if (Bytecodes::ScaleForUnsignedOperand(delta) <= OperandScale::kDouble) {
     334             :     // The jump fits within the range of an Imm16 operand, so cancel
     335             :     // the reservation and jump directly.
     336       15944 :     constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
     337             :     WriteUnalignedUInt16(reinterpret_cast<Address>(operand_bytes),
     338             :                          static_cast<uint16_t>(delta));
     339             :   } else {
     340             :     // The jump does not fit within the range of an Imm16 operand, so
     341             :     // commit reservation putting the offset into the constant pool,
     342             :     // and update the jump instruction and operand.
     343             :     size_t entry = constant_array_builder()->CommitReservedEntry(
     344           5 :         OperandSize::kShort, Smi::FromInt(delta));
     345           5 :     jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
     346           5 :     bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
     347           5 :     WriteUnalignedUInt16(reinterpret_cast<Address>(operand_bytes),
     348             :                          static_cast<uint16_t>(entry));
     349             :   }
     350             :   DCHECK(bytecodes()->at(operand_location) == k8BitJumpPlaceholder &&
     351             :          bytecodes()->at(operand_location + 1) == k8BitJumpPlaceholder);
     352       31898 :   bytecodes()->at(operand_location++) = operand_bytes[0];
     353       15949 :   bytecodes()->at(operand_location) = operand_bytes[1];
     354       15949 : }
     355             : 
     356           5 : void BytecodeArrayWriter::PatchJumpWith32BitOperand(size_t jump_location,
     357             :                                                     int delta) {
     358             :   DCHECK(Bytecodes::IsJumpImmediate(
     359             :       Bytecodes::FromByte(bytecodes()->at(jump_location))));
     360           5 :   constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad);
     361             :   uint8_t operand_bytes[4];
     362           5 :   WriteUnalignedUInt32(reinterpret_cast<Address>(operand_bytes),
     363             :                        static_cast<uint32_t>(delta));
     364           5 :   size_t operand_location = jump_location + 1;
     365             :   DCHECK(bytecodes()->at(operand_location) == k8BitJumpPlaceholder &&
     366             :          bytecodes()->at(operand_location + 1) == k8BitJumpPlaceholder &&
     367             :          bytecodes()->at(operand_location + 2) == k8BitJumpPlaceholder &&
     368             :          bytecodes()->at(operand_location + 3) == k8BitJumpPlaceholder);
     369          10 :   bytecodes()->at(operand_location++) = operand_bytes[0];
     370          10 :   bytecodes()->at(operand_location++) = operand_bytes[1];
     371          10 :   bytecodes()->at(operand_location++) = operand_bytes[2];
     372           5 :   bytecodes()->at(operand_location) = operand_bytes[3];
     373           5 : }
     374             : 
     375     1820863 : void BytecodeArrayWriter::PatchJump(size_t jump_target, size_t jump_location) {
     376     1820863 :   Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location));
     377     1820863 :   int delta = static_cast<int>(jump_target - jump_location);
     378             :   int prefix_offset = 0;
     379             :   OperandScale operand_scale = OperandScale::kSingle;
     380     1820863 :   if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) {
     381             :     // If a prefix scaling bytecode is emitted the target offset is one
     382             :     // less than the case of no prefix scaling bytecode.
     383       15954 :     delta -= 1;
     384             :     prefix_offset = 1;
     385       15954 :     operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode);
     386             :     jump_bytecode =
     387       15954 :         Bytecodes::FromByte(bytecodes()->at(jump_location + prefix_offset));
     388             :   }
     389             : 
     390             :   DCHECK(Bytecodes::IsJump(jump_bytecode));
     391     1820863 :   switch (operand_scale) {
     392             :     case OperandScale::kSingle:
     393     1804909 :       PatchJumpWith8BitOperand(jump_location, delta);
     394     1804908 :       break;
     395             :     case OperandScale::kDouble:
     396       15949 :       PatchJumpWith16BitOperand(jump_location + prefix_offset, delta);
     397       15949 :       break;
     398             :     case OperandScale::kQuadruple:
     399           5 :       PatchJumpWith32BitOperand(jump_location + prefix_offset, delta);
     400           5 :       break;
     401             :     default:
     402           0 :       UNREACHABLE();
     403             :   }
     404     1820862 :   unbound_jumps_--;
     405     1820862 : }
     406             : 
     407      253906 : void BytecodeArrayWriter::EmitJumpLoop(BytecodeNode* node,
     408             :                                        BytecodeLoopHeader* loop_header) {
     409             :   DCHECK_EQ(node->bytecode(), Bytecode::kJumpLoop);
     410             :   DCHECK_EQ(0u, node->operand(0));
     411             : 
     412             :   size_t current_offset = bytecodes()->size();
     413             : 
     414      253906 :   CHECK_GE(current_offset, loop_header->offset());
     415      253906 :   CHECK_LE(current_offset, static_cast<size_t>(kMaxUInt32));
     416             :   // Label has been bound already so this is a backwards jump.
     417             :   uint32_t delta =
     418      253906 :       static_cast<uint32_t>(current_offset - loop_header->offset());
     419             :   OperandScale operand_scale = Bytecodes::ScaleForUnsignedOperand(delta);
     420      253906 :   if (operand_scale > OperandScale::kSingle) {
     421             :     // Adjust for scaling byte prefix for wide jump offset.
     422        8383 :     delta += 1;
     423             :   }
     424      253906 :   node->update_operand0(delta);
     425      253913 :   EmitBytecode(node);
     426      253915 : }
     427             : 
     428     1820868 : void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
     429             :   DCHECK(Bytecodes::IsForwardJump(node->bytecode()));
     430             :   DCHECK_EQ(0u, node->operand(0));
     431             : 
     432             :   size_t current_offset = bytecodes()->size();
     433             : 
     434             :   // The label has not yet been bound so this is a forward reference
     435             :   // that will be patched when the label is bound. We create a
     436             :   // reservation in the constant pool so the jump can be patched
     437             :   // when the label is bound. The reservation means the maximum size
     438             :   // of the operand for the constant is known and the jump can
     439             :   // be emitted into the bytecode stream with space for the operand.
     440     1820868 :   unbound_jumps_++;
     441             :   label->set_referrer(current_offset);
     442             :   OperandSize reserved_operand_size =
     443     1820868 :       constant_array_builder()->CreateReservedEntry();
     444             :   DCHECK_NE(Bytecode::kJumpLoop, node->bytecode());
     445     1820863 :   switch (reserved_operand_size) {
     446             :     case OperandSize::kNone:
     447           0 :       UNREACHABLE();
     448             :       break;
     449             :     case OperandSize::kByte:
     450     1804914 :       node->update_operand0(k8BitJumpPlaceholder);
     451     1804911 :       break;
     452             :     case OperandSize::kShort:
     453       15949 :       node->update_operand0(k16BitJumpPlaceholder);
     454       15949 :       break;
     455             :     case OperandSize::kQuad:
     456           5 :       node->update_operand0(k32BitJumpPlaceholder);
     457           5 :       break;
     458             :   }
     459     1820860 :   EmitBytecode(node);
     460     1820852 : }
     461             : 
     462           0 : void BytecodeArrayWriter::EmitSwitch(BytecodeNode* node,
     463             :                                      BytecodeJumpTable* jump_table) {
     464             :   DCHECK(Bytecodes::IsSwitch(node->bytecode()));
     465             : 
     466             :   size_t current_offset = bytecodes()->size();
     467       19845 :   if (node->operand_scale() > OperandScale::kSingle) {
     468             :     // Adjust for scaling byte prefix.
     469         122 :     current_offset += 1;
     470             :   }
     471             :   jump_table->set_switch_bytecode_offset(current_offset);
     472             : 
     473       19845 :   EmitBytecode(node);
     474           0 : }
     475             : 
     476             : }  // namespace interpreter
     477             : }  // namespace internal
     478      121996 : }  // namespace v8

Generated by: LCOV version 1.10