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

Generated by: LCOV version 1.10