| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "test/unittests/compiler/interpreter-assembler-unittest.h" | 5 #include "test/unittests/compiler/interpreter-assembler-unittest.h" |
| 6 | 6 |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
| 9 #include "src/unique.h" | 9 #include "src/unique.h" |
| 10 #include "test/unittests/compiler/compiler-test-utils.h" | 10 #include "test/unittests/compiler/compiler-test-utils.h" |
| 11 #include "test/unittests/compiler/node-test-utils.h" | 11 #include "test/unittests/compiler/node-test-utils.h" |
| 12 | 12 |
| 13 using ::testing::_; |
| 14 |
| 13 namespace v8 { | 15 namespace v8 { |
| 14 namespace internal { | 16 namespace internal { |
| 15 namespace compiler { | 17 namespace compiler { |
| 16 | 18 |
| 17 const interpreter::Bytecode kBytecodes[] = { | 19 const interpreter::Bytecode kBytecodes[] = { |
| 18 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, | 20 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, |
| 19 BYTECODE_LIST(DEFINE_BYTECODE) | 21 BYTECODE_LIST(DEFINE_BYTECODE) |
| 20 #undef DEFINE_BYTECODE | 22 #undef DEFINE_BYTECODE |
| 21 }; | 23 }; |
| 22 | 24 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 Matcher<Node*> code_target_matcher = m.IsLoad( | 88 Matcher<Node*> code_target_matcher = m.IsLoad( |
| 87 kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter), | 89 kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter), |
| 88 IsWord32Shl(target_bytecode_matcher, | 90 IsWord32Shl(target_bytecode_matcher, |
| 89 IsInt32Constant(kPointerSizeLog2))); | 91 IsInt32Constant(kPointerSizeLog2))); |
| 90 | 92 |
| 91 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); | 93 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); |
| 92 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); | 94 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); |
| 93 EXPECT_THAT( | 95 EXPECT_THAT( |
| 94 tail_call_node, | 96 tail_call_node, |
| 95 IsTailCall(m.call_descriptor(), code_target_matcher, | 97 IsTailCall(m.call_descriptor(), code_target_matcher, |
| 98 IsParameter(Linkage::kInterpreterAccumulatorParameter), |
| 99 IsParameter(Linkage::kInterpreterRegisterFileParameter), |
| 96 next_bytecode_offset_matcher, | 100 next_bytecode_offset_matcher, |
| 97 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 101 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 98 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 102 IsParameter(Linkage::kInterpreterDispatchTableParameter), |
| 99 graph->start(), graph->start())); | 103 graph->start(), graph->start())); |
| 100 } | 104 } |
| 101 } | 105 } |
| 102 | 106 |
| 103 | 107 |
| 104 TARGET_TEST_F(InterpreterAssemblerTest, Return) { | 108 TARGET_TEST_F(InterpreterAssemblerTest, Return) { |
| 105 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 109 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 106 InterpreterAssemblerForTest m(this, bytecode); | 110 InterpreterAssemblerForTest m(this, bytecode); |
| 107 m.Return(); | 111 m.Return(); |
| 108 Graph* graph = m.GetCompletedGraph(); | 112 Graph* graph = m.GetCompletedGraph(); |
| 109 | 113 |
| 110 Node* end = graph->end(); | 114 Node* end = graph->end(); |
| 111 EXPECT_EQ(1, end->InputCount()); | 115 EXPECT_EQ(1, end->InputCount()); |
| 112 Node* tail_call_node = end->InputAt(0); | 116 Node* tail_call_node = end->InputAt(0); |
| 113 | 117 |
| 114 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); | 118 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); |
| 115 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); | 119 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); |
| 116 Matcher<Unique<HeapObject>> exit_trampoline( | 120 Matcher<Unique<HeapObject>> exit_trampoline( |
| 117 Unique<HeapObject>::CreateImmovable( | 121 Unique<HeapObject>::CreateImmovable( |
| 118 isolate()->builtins()->InterpreterExitTrampoline())); | 122 isolate()->builtins()->InterpreterExitTrampoline())); |
| 119 EXPECT_THAT( | 123 EXPECT_THAT( |
| 120 tail_call_node, | 124 tail_call_node, |
| 121 IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), | 125 IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), |
| 126 IsParameter(Linkage::kInterpreterAccumulatorParameter), |
| 127 IsParameter(Linkage::kInterpreterRegisterFileParameter), |
| 122 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 128 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), |
| 123 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 129 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 124 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 130 IsParameter(Linkage::kInterpreterDispatchTableParameter), |
| 125 graph->start(), graph->start())); | 131 graph->start(), graph->start())); |
| 126 } | 132 } |
| 127 } | 133 } |
| 128 | 134 |
| 129 | 135 |
| 130 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { | 136 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
| 131 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 137 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 132 InterpreterAssemblerForTest m(this, bytecode); | 138 InterpreterAssemblerForTest m(this, bytecode); |
| 133 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); | 139 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); |
| 134 for (int i = 0; i < number_of_operands; i++) { | 140 for (int i = 0; i < number_of_operands; i++) { |
| 135 Node* load_arg_node = m.BytecodeOperand(i); | 141 Node* load_arg_node = m.BytecodeOperand(i); |
| 136 EXPECT_THAT( | 142 EXPECT_THAT( |
| 137 load_arg_node, | 143 load_arg_node, |
| 138 m.IsLoad( | 144 m.IsLoad( |
| 139 kMachUint8, | 145 kMachUint8, |
| 140 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 146 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 141 IsIntPtrAdd( | 147 IsIntPtrAdd( |
| 142 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 148 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), |
| 143 IsInt32Constant(1 + i)))); | 149 IsInt32Constant(1 + i)))); |
| 144 } | 150 } |
| 145 } | 151 } |
| 146 } | 152 } |
| 147 | 153 |
| 148 | 154 |
| 149 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegisterFixed) { | 155 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperandSignExtended) { |
| 150 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 156 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 151 InterpreterAssemblerForTest m(this, bytecode); | 157 InterpreterAssemblerForTest m(this, bytecode); |
| 152 for (int i = 0; i < m.kMaxRegisterIndex; i++) { | 158 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); |
| 153 Node* load_reg_node = m.LoadRegister(i); | 159 for (int i = 0; i < number_of_operands; i++) { |
| 154 EXPECT_THAT(load_reg_node, | 160 Node* load_arg_node = m.BytecodeOperandSignExtended(i); |
| 155 m.IsLoad(kMachPtr, IsLoadFramePointer(), | 161 Matcher<Node*> load_matcher = m.IsLoad( |
| 156 IsInt32Constant(m.kFirstRegisterOffsetFromFp - | 162 kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 157 (i << kPointerSizeLog2)))); | 163 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), |
| 164 IsInt32Constant(1 + i))); |
| 165 if (kPointerSize == 8) { |
| 166 load_matcher = IsChangeInt32ToInt64(load_matcher); |
| 167 } |
| 168 EXPECT_THAT(load_arg_node, load_matcher); |
| 158 } | 169 } |
| 159 } | 170 } |
| 160 } | 171 } |
| 161 | 172 |
| 162 | 173 |
| 174 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { |
| 175 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 176 InterpreterAssemblerForTest m(this, bytecode); |
| 177 // Should be incoming accumulator if not set. |
| 178 EXPECT_THAT(m.GetAccumulator(), |
| 179 IsParameter(Linkage::kInterpreterAccumulatorParameter)); |
| 180 |
| 181 // Should be set by SedtAccumulator. |
| 182 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); |
| 183 m.SetAccumulator(accumulator_value_1); |
| 184 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); |
| 185 Node* accumulator_value_2 = m.Int32Constant(42); |
| 186 m.SetAccumulator(accumulator_value_2); |
| 187 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); |
| 188 |
| 189 // Should be passed to next bytecode handler on dispatch. |
| 190 m.Dispatch(); |
| 191 Graph* graph = m.GetCompletedGraph(); |
| 192 |
| 193 Node* end = graph->end(); |
| 194 EXPECT_EQ(1, end->InputCount()); |
| 195 Node* tail_call_node = end->InputAt(0); |
| 196 |
| 197 EXPECT_THAT(tail_call_node, |
| 198 IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _, |
| 199 _, graph->start(), graph->start())); |
| 200 } |
| 201 } |
| 202 |
| 203 |
| 163 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { | 204 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { |
| 164 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 205 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 165 InterpreterAssemblerForTest m(this, bytecode); | 206 InterpreterAssemblerForTest m(this, bytecode); |
| 166 Node* reg_index_node = m.Int32Constant(44); | 207 Node* reg_index_node = m.Int32Constant(44); |
| 167 Node* load_reg_node = m.LoadRegister(reg_index_node); | 208 Node* load_reg_node = m.LoadRegister(reg_index_node); |
| 168 EXPECT_THAT( | 209 EXPECT_THAT( |
| 169 load_reg_node, | 210 load_reg_node, |
| 170 m.IsLoad(kMachPtr, IsLoadFramePointer(), | 211 m.IsLoad(kMachPtr, |
| 171 IsIntPtrSub(IsInt32Constant(m.kFirstRegisterOffsetFromFp), | 212 IsParameter(Linkage::kInterpreterRegisterFileParameter), |
| 172 IsWordShl(reg_index_node, | 213 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); |
| 173 IsInt32Constant(kPointerSizeLog2))))); | |
| 174 } | 214 } |
| 175 } | 215 } |
| 176 | 216 |
| 177 | |
| 178 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegisterFixed) { | |
| 179 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | |
| 180 InterpreterAssemblerForTest m(this, bytecode); | |
| 181 Node* store_value = m.Int32Constant(0xdeadbeef); | |
| 182 for (int i = 0; i < m.kMaxRegisterIndex; i++) { | |
| 183 Node* store_reg_node = m.StoreRegister(store_value, i); | |
| 184 EXPECT_THAT(store_reg_node, | |
| 185 m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), | |
| 186 IsLoadFramePointer(), | |
| 187 IsInt32Constant(m.kFirstRegisterOffsetFromFp - | |
| 188 (i << kPointerSizeLog2)), | |
| 189 store_value)); | |
| 190 } | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 | 217 |
| 195 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { | 218 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { |
| 196 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 219 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 197 InterpreterAssemblerForTest m(this, bytecode); | 220 InterpreterAssemblerForTest m(this, bytecode); |
| 198 Node* store_value = m.Int32Constant(0xdeadbeef); | 221 Node* store_value = m.Int32Constant(0xdeadbeef); |
| 199 Node* reg_index_node = m.Int32Constant(44); | 222 Node* reg_index_node = m.Int32Constant(44); |
| 200 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); | 223 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); |
| 201 EXPECT_THAT( | 224 EXPECT_THAT( |
| 202 store_reg_node, | 225 store_reg_node, |
| 203 m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), | 226 m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), |
| 204 IsLoadFramePointer(), | 227 IsParameter(Linkage::kInterpreterRegisterFileParameter), |
| 205 IsIntPtrSub(IsInt32Constant(m.kFirstRegisterOffsetFromFp), | 228 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), |
| 206 IsWordShl(reg_index_node, | |
| 207 IsInt32Constant(kPointerSizeLog2))), | |
| 208 store_value)); | 229 store_value)); |
| 209 } | 230 } |
| 210 } | 231 } |
| 211 | 232 |
| 212 } // namespace compiler | 233 } // namespace compiler |
| 213 } // namespace internal | 234 } // namespace internal |
| 214 } // namespace v8 | 235 } // namespace v8 |
| OLD | NEW |