LCOV - code coverage report
Current view: top level - test/unittests/interpreter - interpreter-assembler-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 154 210 73.3 %
Date: 2019-02-19 Functions: 30 40 75.0 %

          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 "test/unittests/interpreter/interpreter-assembler-unittest.h"
       6             : 
       7             : #include "src/code-factory.h"
       8             : #include "src/compiler/node.h"
       9             : #include "src/interface-descriptors.h"
      10             : #include "src/isolate.h"
      11             : #include "src/objects-inl.h"
      12             : #include "test/unittests/compiler/compiler-test-utils.h"
      13             : #include "test/unittests/compiler/node-test-utils.h"
      14             : 
      15             : using ::testing::_;
      16             : using v8::internal::compiler::Node;
      17             : 
      18             : namespace c = v8::internal::compiler;
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : namespace interpreter {
      23             : namespace interpreter_assembler_unittest {
      24             : 
      25        1446 : InterpreterAssemblerTestState::InterpreterAssemblerTestState(
      26             :     InterpreterAssemblerTest* test, Bytecode bytecode)
      27             :     : compiler::CodeAssemblerState(
      28             :           test->isolate(), test->zone(), InterpreterDispatchDescriptor{},
      29             :           Code::BYTECODE_HANDLER, Bytecodes::ToString(bytecode),
      30        4338 :           PoisoningMitigationLevel::kPoisonCriticalOnly) {}
      31             : 
      32             : const interpreter::Bytecode kBytecodes[] = {
      33             : #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,
      34             :     BYTECODE_LIST(DEFINE_BYTECODE)
      35             : #undef DEFINE_BYTECODE
      36             : };
      37             : 
      38             : 
      39        1446 : InterpreterAssemblerTest::InterpreterAssemblerForTest::
      40        1446 :     ~InterpreterAssemblerForTest() {
      41             :   // Tests don't necessarily read and write accumulator but
      42             :   // InterpreterAssembler checks accumulator uses.
      43        4338 :   if (Bytecodes::ReadsAccumulator(bytecode())) {
      44         856 :     GetAccumulator();
      45             :   }
      46        1446 :   if (Bytecodes::WritesAccumulator(bytecode())) {
      47        1028 :     SetAccumulator(nullptr);
      48             :   }
      49        1446 : }
      50             : 
      51        2868 : Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
      52             :     const Matcher<c::LoadRepresentation>& rep_matcher,
      53             :     const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
      54             :     LoadSensitivity needs_poisoning) {
      55        2868 :   CHECK_NE(LoadSensitivity::kUnsafe, needs_poisoning);
      56        2868 :   CHECK_NE(PoisoningMitigationLevel::kPoisonAll, poisoning_level());
      57        2868 :   if (poisoning_level() == PoisoningMitigationLevel::kPoisonCriticalOnly &&
      58             :       needs_poisoning == LoadSensitivity::kCritical) {
      59             :     return ::i::compiler::IsPoisonedLoad(rep_matcher, base_matcher,
      60        3798 :                                          index_matcher, _, _);
      61             :   }
      62        4806 :   return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _);
      63             : }
      64             : 
      65           0 : Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
      66             :     const Matcher<c::StoreRepresentation>& rep_matcher,
      67             :     const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
      68             :     const Matcher<Node*>& value_matcher) {
      69             :   return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher,
      70           0 :                                 value_matcher, _, _);
      71             : }
      72             : 
      73           0 : Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsWordNot(
      74             :     const Matcher<Node*>& value_matcher) {
      75             :   return kSystemPointerSize == 8
      76             :              ? IsWord64Xor(value_matcher, c::IsInt64Constant(-1))
      77           0 :              : IsWord32Xor(value_matcher, c::IsInt32Constant(-1));
      78             : }
      79             : 
      80             : Matcher<Node*>
      81         188 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand(
      82             :     int offset, LoadSensitivity needs_poisoning) {
      83             :   return IsLoad(
      84             :       MachineType::Uint8(),
      85             :       c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
      86             :       c::IsIntPtrAdd(
      87             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
      88             :           c::IsIntPtrConstant(offset)),
      89        1692 :       needs_poisoning);
      90             : }
      91             : 
      92             : Matcher<Node*>
      93         130 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand(
      94             :     int offset, LoadSensitivity needs_poisoning) {
      95             :   return IsLoad(
      96             :       MachineType::Int8(),
      97             :       c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
      98             :       c::IsIntPtrAdd(
      99             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     100             :           c::IsIntPtrConstant(offset)),
     101        1170 :       needs_poisoning);
     102             : }
     103             : 
     104             : Matcher<Node*>
     105         170 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand(
     106             :     int offset, LoadSensitivity needs_poisoning) {
     107         170 :   if (TargetSupportsUnalignedAccess()) {
     108             :     return IsLoad(
     109             :         MachineType::Uint16(),
     110             :         c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     111             :         c::IsIntPtrAdd(
     112             :             c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     113             :             c::IsIntPtrConstant(offset)),
     114        1530 :         needs_poisoning);
     115             :   } else {
     116             : #if V8_TARGET_LITTLE_ENDIAN
     117             :     const int kStep = -1;
     118             :     const int kMsbOffset = 1;
     119             : #elif V8_TARGET_BIG_ENDIAN
     120             :     const int kStep = 1;
     121             :     const int kMsbOffset = 0;
     122             : #else
     123             : #error "Unknown Architecture"
     124             : #endif
     125           0 :     Matcher<Node*> bytes[2];
     126           0 :     for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
     127           0 :       bytes[i] = IsLoad(
     128             :           MachineType::Uint8(),
     129             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     130             :           c::IsIntPtrAdd(
     131             :               c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     132           0 :               c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)),
     133             :           needs_poisoning);
     134             :     }
     135             :     return c::IsWord32Or(
     136           0 :         c::IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)), bytes[1]);
     137             :   }
     138             : }
     139             : 
     140             : Matcher<Node*>
     141         130 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand(
     142             :     int offset, LoadSensitivity needs_poisoning) {
     143         130 :   if (TargetSupportsUnalignedAccess()) {
     144             :     return IsLoad(
     145             :         MachineType::Int16(),
     146             :         c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     147             :         c::IsIntPtrAdd(
     148             :             c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     149             :             c::IsIntPtrConstant(offset)),
     150        1170 :         needs_poisoning);
     151             :   } else {
     152             : #if V8_TARGET_LITTLE_ENDIAN
     153             :     const int kStep = -1;
     154             :     const int kMsbOffset = 1;
     155             : #elif V8_TARGET_BIG_ENDIAN
     156             :     const int kStep = 1;
     157             :     const int kMsbOffset = 0;
     158             : #else
     159             : #error "Unknown Architecture"
     160             : #endif
     161           0 :     Matcher<Node*> bytes[2];
     162           0 :     for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
     163           0 :       bytes[i] = IsLoad(
     164             :           (i == 0) ? MachineType::Int8() : MachineType::Uint8(),
     165             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     166             :           c::IsIntPtrAdd(
     167             :               c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     168           0 :               c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)),
     169             :           needs_poisoning);
     170             :     }
     171             :     return c::IsWord32Or(
     172           0 :         c::IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)), bytes[1]);
     173             :   }
     174             : }
     175             : 
     176             : Matcher<Node*>
     177         158 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand(
     178             :     int offset, LoadSensitivity needs_poisoning) {
     179         158 :   if (TargetSupportsUnalignedAccess()) {
     180             :     return IsLoad(
     181             :         MachineType::Uint32(),
     182             :         c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     183             :         c::IsIntPtrAdd(
     184             :             c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     185             :             c::IsIntPtrConstant(offset)),
     186        1422 :         needs_poisoning);
     187             :   } else {
     188             : #if V8_TARGET_LITTLE_ENDIAN
     189             :     const int kStep = -1;
     190             :     const int kMsbOffset = 3;
     191             : #elif V8_TARGET_BIG_ENDIAN
     192             :     const int kStep = 1;
     193             :     const int kMsbOffset = 0;
     194             : #else
     195             : #error "Unknown Architecture"
     196             : #endif
     197           0 :     Matcher<Node*> bytes[4];
     198           0 :     for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
     199           0 :       bytes[i] = IsLoad(
     200             :           MachineType::Uint8(),
     201             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     202             :           c::IsIntPtrAdd(
     203             :               c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     204           0 :               c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)),
     205             :           needs_poisoning);
     206             :     }
     207             :     return c::IsWord32Or(
     208             :         c::IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
     209             :         c::IsWord32Or(
     210             :             c::IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
     211             :             c::IsWord32Or(
     212             :                 c::IsWord32Shl(bytes[2], c::IsInt32Constant(1 * kBitsPerByte)),
     213           0 :                 bytes[3])));
     214             :   }
     215             : }
     216             : 
     217             : Matcher<Node*>
     218         130 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand(
     219             :     int offset, LoadSensitivity needs_poisoning) {
     220         130 :   if (TargetSupportsUnalignedAccess()) {
     221             :     return IsLoad(
     222             :         MachineType::Int32(),
     223             :         c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     224             :         c::IsIntPtrAdd(
     225             :             c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     226             :             c::IsIntPtrConstant(offset)),
     227        1170 :         needs_poisoning);
     228             :   } else {
     229             : #if V8_TARGET_LITTLE_ENDIAN
     230             :     const int kStep = -1;
     231             :     int kMsbOffset = 3;
     232             : #elif V8_TARGET_BIG_ENDIAN
     233             :     const int kStep = 1;
     234             :     int kMsbOffset = 0;
     235             : #else
     236             : #error "Unknown Architecture"
     237             : #endif
     238           0 :     Matcher<Node*> bytes[4];
     239           0 :     for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
     240           0 :       bytes[i] = IsLoad(
     241             :           (i == 0) ? MachineType::Int8() : MachineType::Uint8(),
     242             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     243             :           c::IsIntPtrAdd(
     244             :               c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     245           0 :               c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)),
     246             :           needs_poisoning);
     247             :     }
     248             :     return c::IsWord32Or(
     249             :         c::IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
     250             :         c::IsWord32Or(
     251             :             c::IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
     252             :             c::IsWord32Or(
     253             :                 c::IsWord32Shl(bytes[2], c::IsInt32Constant(1 * kBitsPerByte)),
     254           0 :                 bytes[3])));
     255             :   }
     256             : }
     257             : 
     258             : Matcher<Node*>
     259         390 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedOperand(
     260             :     int offset, OperandSize operand_size, LoadSensitivity needs_poisoning) {
     261         390 :   switch (operand_size) {
     262             :     case OperandSize::kByte:
     263         130 :       return IsSignedByteOperand(offset, needs_poisoning);
     264             :     case OperandSize::kShort:
     265         130 :       return IsSignedShortOperand(offset, needs_poisoning);
     266             :     case OperandSize::kQuad:
     267         130 :       return IsSignedQuadOperand(offset, needs_poisoning);
     268             :     case OperandSize::kNone:
     269           0 :       UNREACHABLE();
     270             :   }
     271           0 :   return nullptr;
     272             : }
     273             : 
     274             : Matcher<Node*>
     275         516 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedOperand(
     276             :     int offset, OperandSize operand_size, LoadSensitivity needs_poisoning) {
     277         516 :   switch (operand_size) {
     278             :     case OperandSize::kByte:
     279         188 :       return IsUnsignedByteOperand(offset, needs_poisoning);
     280             :     case OperandSize::kShort:
     281         170 :       return IsUnsignedShortOperand(offset, needs_poisoning);
     282             :     case OperandSize::kQuad:
     283         158 :       return IsUnsignedQuadOperand(offset, needs_poisoning);
     284             :     case OperandSize::kNone:
     285           0 :       UNREACHABLE();
     286             :   }
     287           0 :   return nullptr;
     288             : }
     289             : 
     290             : Matcher<compiler::Node*>
     291         336 : InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoadRegisterOperand(
     292             :     int offset, OperandSize operand_size) {
     293             :   Matcher<compiler::Node*> reg_operand = IsChangeInt32ToIntPtr(
     294         672 :       IsSignedOperand(offset, operand_size, LoadSensitivity::kSafe));
     295             :   return IsBitcastWordToTagged(IsLoad(
     296             :       MachineType::Pointer(), c::IsLoadParentFramePointer(),
     297             :       c::IsWordShl(reg_operand, c::IsIntPtrConstant(kSystemPointerSizeLog2)),
     298        2688 :       LoadSensitivity::kCritical));
     299             : }
     300             : 
     301       15189 : TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
     302             :   // If debug code is enabled we emit extra code in Jump.
     303           2 :   if (FLAG_debug_code) return;
     304             : 
     305           1 :   int jump_offsets[] = {-9710, -77, 0, +3, +97109};
     306           5 :   TRACED_FOREACH(int, jump_offset, jump_offsets) {
     307           5 :     TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     308           3 :       if (!interpreter::Bytecodes::IsJump(bytecode)) return;
     309             : 
     310           0 :       InterpreterAssemblerTestState state(this, bytecode);
     311           0 :       InterpreterAssemblerForTest m(&state, bytecode);
     312           0 :       Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset));
     313             : 
     314             :       Matcher<Node*> next_bytecode_offset_matcher = c::IsIntPtrAdd(
     315             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
     316           0 :           c::IsIntPtrConstant(jump_offset));
     317             :       Matcher<Node*> target_bytecode_matcher =
     318           0 :           m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher);
     319           0 :       target_bytecode_matcher =
     320             :           c::IsChangeUint32ToWord(target_bytecode_matcher);
     321             :       Matcher<Node*> code_target_matcher = m.IsLoad(
     322             :           MachineType::Pointer(),
     323             :           c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable),
     324             :           c::IsWordShl(target_bytecode_matcher,
     325           0 :                        c::IsIntPtrConstant(kSystemPointerSizeLog2)));
     326             : 
     327           0 :       EXPECT_THAT(
     328             :           tail_call_node,
     329             :           c::IsTailCall(
     330             :               _, code_target_matcher,
     331             :               c::IsParameter(InterpreterDispatchDescriptor::kAccumulator),
     332             :               next_bytecode_offset_matcher, _,
     333             :               c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable), _,
     334           0 :               _));
     335           0 :     }
     336           0 :   }
     337             : }
     338             : 
     339       15189 : TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
     340             :   static const OperandScale kOperandScales[] = {
     341             :       OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple};
     342        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     343        3780 :     TRACED_FOREACH(interpreter::OperandScale, operand_scale, kOperandScales) {
     344         540 :       InterpreterAssemblerTestState state(this, bytecode);
     345        1080 :       InterpreterAssemblerForTest m(&state, bytecode, operand_scale);
     346             :       int number_of_operands =
     347         540 :           interpreter::Bytecodes::NumberOfOperands(bytecode);
     348        1446 :       for (int i = 0; i < number_of_operands; i++) {
     349             :         int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i,
     350         906 :                                                               operand_scale);
     351             :         OperandType operand_type =
     352         906 :             interpreter::Bytecodes::GetOperandType(bytecode, i);
     353             :         OperandSize operand_size =
     354         906 :             Bytecodes::SizeOfOperand(operand_type, operand_scale);
     355         906 :         switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
     356             :           case interpreter::OperandType::kRegCount:
     357         156 :             EXPECT_THAT(m.BytecodeOperandCount(i),
     358             :                         m.IsUnsignedOperand(offset, operand_size,
     359           0 :                                             LoadSensitivity::kCritical));
     360          39 :             break;
     361             :           case interpreter::OperandType::kFlag8:
     362         108 :             EXPECT_THAT(m.BytecodeOperandFlag(i),
     363             :                         m.IsUnsignedOperand(offset, operand_size,
     364           0 :                                             LoadSensitivity::kCritical));
     365          27 :             break;
     366             :           case interpreter::OperandType::kIdx:
     367        1785 :             EXPECT_THAT(m.BytecodeOperandIdx(i),
     368             :                         c::IsChangeUint32ToWord(m.IsUnsignedOperand(
     369           0 :                             offset, operand_size, LoadSensitivity::kCritical)));
     370         357 :             break;
     371             :           case interpreter::OperandType::kNativeContextIndex:
     372          15 :             EXPECT_THAT(m.BytecodeOperandNativeContextIndex(i),
     373             :                         c::IsChangeUint32ToWord(m.IsUnsignedOperand(
     374           0 :                             offset, operand_size, LoadSensitivity::kCritical)));
     375           3 :             break;
     376             :           case interpreter::OperandType::kUImm:
     377         300 :             EXPECT_THAT(m.BytecodeOperandUImm(i),
     378             :                         m.IsUnsignedOperand(offset, operand_size,
     379           0 :                                             LoadSensitivity::kCritical));
     380          75 :             break;
     381             :           case interpreter::OperandType::kImm: {
     382         216 :             EXPECT_THAT(m.BytecodeOperandImm(i),
     383             :                         m.IsSignedOperand(offset, operand_size,
     384           0 :                                           LoadSensitivity::kCritical));
     385          54 :             break;
     386             :           }
     387             :           case interpreter::OperandType::kRuntimeId:
     388          48 :             EXPECT_THAT(m.BytecodeOperandRuntimeId(i),
     389             :                         m.IsUnsignedOperand(offset, operand_size,
     390           0 :                                             LoadSensitivity::kCritical));
     391          12 :             break;
     392             :           case interpreter::OperandType::kIntrinsicId:
     393          12 :             EXPECT_THAT(m.BytecodeOperandIntrinsicId(i),
     394             :                         m.IsUnsignedOperand(offset, operand_size,
     395           0 :                                             LoadSensitivity::kCritical));
     396           3 :             break;
     397             :           case interpreter::OperandType::kRegList:
     398             :           case interpreter::OperandType::kReg:
     399             :           case interpreter::OperandType::kRegPair:
     400             :           case interpreter::OperandType::kRegOut:
     401             :           case interpreter::OperandType::kRegOutList:
     402             :           case interpreter::OperandType::kRegOutPair:
     403             :           case interpreter::OperandType::kRegOutTriple:
     404        1344 :             EXPECT_THAT(m.LoadRegisterAtOperandIndex(i),
     405           0 :                         m.IsLoadRegisterOperand(offset, operand_size));
     406         336 :             break;
     407             :           case interpreter::OperandType::kNone:
     408           0 :             UNREACHABLE();
     409             :             break;
     410             :         }
     411             :       }
     412         540 :     }
     413         180 :   }
     414           1 : }
     415             : 
     416       15189 : TARGET_TEST_F(InterpreterAssemblerTest, GetContext) {
     417        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     418         180 :     InterpreterAssemblerTestState state(this, bytecode);
     419         360 :     InterpreterAssemblerForTest m(&state, bytecode);
     420        1620 :     EXPECT_THAT(
     421             :         m.GetContext(),
     422             :         IsBitcastWordToTagged(m.IsLoad(
     423             :             MachineType::Pointer(), c::IsLoadParentFramePointer(),
     424             :             c::IsIntPtrConstant(Register::current_context().ToOperand() *
     425           0 :                                 kSystemPointerSize))));
     426         180 :   }
     427           1 : }
     428             : 
     429       15189 : TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
     430        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     431         180 :     InterpreterAssemblerTestState state(this, bytecode);
     432         360 :     InterpreterAssemblerForTest m(&state, bytecode);
     433             :     {
     434         360 :       Node* index = m.IntPtrConstant(2);
     435         180 :       Node* load_constant = m.LoadConstantPoolEntry(index);
     436             :       Matcher<Node*> constant_pool_matcher = m.IsLoad(
     437             :           MachineType::AnyTagged(),
     438             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     439             :           c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
     440         900 :                               kHeapObjectTag));
     441        1080 :       EXPECT_THAT(
     442             :           load_constant,
     443             :           m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher,
     444             :                    c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) -
     445             :                                        kHeapObjectTag),
     446           0 :                    LoadSensitivity::kCritical));
     447             :     }
     448             :     {
     449         180 :       Node* index = m.Parameter(2);
     450         180 :       Node* load_constant = m.LoadConstantPoolEntry(index);
     451             :       Matcher<Node*> constant_pool_matcher = m.IsLoad(
     452             :           MachineType::AnyTagged(),
     453             :           c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
     454             :           c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
     455         900 :                               kHeapObjectTag));
     456        2160 :       EXPECT_THAT(
     457             :           load_constant,
     458             :           m.IsLoad(
     459             :               MachineType::AnyTagged(), constant_pool_matcher,
     460             :               c::IsIntPtrAdd(
     461             :                   c::IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
     462             :                   c::IsWordShl(index,
     463             :                                c::IsIntPtrConstant(kSystemPointerSizeLog2))),
     464           0 :               LoadSensitivity::kCritical));
     465             :     }
     466         180 :   }
     467           1 : }
     468             : 
     469       15189 : TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
     470        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     471         180 :     InterpreterAssemblerTestState state(this, bytecode);
     472         360 :     InterpreterAssemblerForTest m(&state, bytecode);
     473         360 :     Node* object = m.IntPtrConstant(0xDEADBEEF);
     474             :     int offset = 16;
     475         180 :     Node* load_field = m.LoadObjectField(object, offset);
     476        1260 :     EXPECT_THAT(load_field,
     477             :                 m.IsLoad(MachineType::AnyTagged(), object,
     478           0 :                          c::IsIntPtrConstant(offset - kHeapObjectTag)));
     479         180 :   }
     480           1 : }
     481             : 
     482       15189 : TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
     483        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     484         180 :     InterpreterAssemblerTestState state(this, bytecode);
     485         360 :     InterpreterAssemblerForTest m(&state, bytecode);
     486         360 :     Node* arg1 = m.Int32Constant(2);
     487         360 :     Node* arg2 = m.Int32Constant(3);
     488         360 :     Node* context = m.Int32Constant(4);
     489         180 :     Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2);
     490        2880 :     EXPECT_THAT(call_runtime, c::IsCall(_, _, arg1, arg2, _,
     491           0 :                                         c::IsInt32Constant(2), context, _, _));
     492         180 :   }
     493           1 : }
     494             : 
     495       15189 : TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
     496           1 :   const int kResultSizes[] = {1, 2};
     497        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     498        2520 :     TRACED_FOREACH(int, result_size, kResultSizes) {
     499         720 :       if (Bytecodes::IsCallRuntime(bytecode)) {
     500           6 :         InterpreterAssemblerTestState state(this, bytecode);
     501          12 :         InterpreterAssemblerForTest m(&state, bytecode);
     502             :         Callable builtin =
     503           6 :             CodeFactory::InterpreterCEntry(isolate(), result_size);
     504             : 
     505          12 :         Node* function_id = m.Int32Constant(0);
     506             :         InterpreterAssembler::RegListNodePair registers(m.IntPtrConstant(1),
     507          18 :                                                         m.Int32Constant(2));
     508          12 :         Node* context = m.IntPtrConstant(4);
     509             : 
     510             :         Matcher<Node*> function_table = c::IsExternalConstant(
     511             :             ExternalReference::runtime_function_table_address_for_unittests(
     512          12 :                 isolate()));
     513             :         Matcher<Node*> function = c::IsIntPtrAdd(
     514             :             function_table,
     515             :             c::IsChangeUint32ToWord(c::IsInt32Mul(
     516          36 :                 function_id, c::IsInt32Constant(sizeof(Runtime::Function)))));
     517             :         Matcher<Node*> function_entry =
     518             :             m.IsLoad(MachineType::Pointer(), function,
     519          18 :                      c::IsIntPtrConstant(offsetof(Runtime::Function, entry)));
     520             : 
     521             :         Node* call_runtime =
     522           6 :             m.CallRuntimeN(function_id, context, registers, result_size);
     523          78 :         EXPECT_THAT(
     524             :             call_runtime,
     525             :             c::IsCall(_, c::IsHeapConstant(builtin.code()),
     526             :                       registers.reg_count(), registers.base_reg_location(),
     527           0 :                       function_entry, context, _, _));
     528             :       }
     529         360 :     }
     530         180 :   }
     531           1 : }
     532             : 
     533       15189 : TARGET_TEST_F(InterpreterAssemblerTest, LoadFeedbackVector) {
     534        1081 :   TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
     535         180 :     InterpreterAssemblerTestState state(this, bytecode);
     536         360 :     InterpreterAssemblerForTest m(&state, bytecode);
     537         360 :     Node* feedback_vector = m.LoadFeedbackVector();
     538             : 
     539             :     Matcher<Node*> load_function_matcher = IsBitcastWordToTagged(
     540             :         m.IsLoad(MachineType::Pointer(), c::IsLoadParentFramePointer(),
     541         540 :                  c::IsIntPtrConstant(Register::function_closure().ToOperand() *
     542         900 :                                      kSystemPointerSize)));
     543             :     Matcher<Node*> load_vector_cell_matcher = m.IsLoad(
     544             :         MachineType::AnyTagged(), load_function_matcher,
     545         540 :         c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - kHeapObjectTag));
     546        1080 :     EXPECT_THAT(
     547             :         feedback_vector,
     548             :         m.IsLoad(MachineType::AnyTagged(), load_vector_cell_matcher,
     549           0 :                  c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)));
     550         180 :   }
     551           1 : }
     552             : 
     553             : }  // namespace interpreter_assembler_unittest
     554             : }  // namespace interpreter
     555             : }  // namespace internal
     556        9111 : }  // namespace v8

Generated by: LCOV version 1.10