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 |