Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: test/unittests/compiler/interpreter-assembler-unittest.cc

Issue 1673333004: [Interpreter] Make InterpreterAssembler a subclass of CodeStubAssembler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/compiler/interpreter-assembler-unittest.h"
6
7 #include "src/code-factory.h"
8 #include "src/compiler/graph.h"
9 #include "src/compiler/node.h"
10 #include "src/interface-descriptors.h"
11 #include "src/isolate.h"
12 #include "test/unittests/compiler/compiler-test-utils.h"
13 #include "test/unittests/compiler/node-test-utils.h"
14
15 using ::testing::_;
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
21 const interpreter::Bytecode kBytecodes[] = {
22 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,
23 BYTECODE_LIST(DEFINE_BYTECODE)
24 #undef DEFINE_BYTECODE
25 };
26
27
28 Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
29 return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value))
30 : IsInt32Constant(static_cast<int32_t>(value));
31 }
32
33
34 Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
35 const Matcher<Node*>& rhs_matcher) {
36 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher)
37 : IsInt32Add(lhs_matcher, rhs_matcher);
38 }
39
40
41 Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
42 const Matcher<Node*>& rhs_matcher) {
43 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher)
44 : IsInt32Sub(lhs_matcher, rhs_matcher);
45 }
46
47
48 Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
49 const Matcher<Node*>& rhs_matcher) {
50 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher)
51 : IsWord32Shl(lhs_matcher, rhs_matcher);
52 }
53
54
55 Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
56 const Matcher<Node*>& rhs_matcher) {
57 return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher)
58 : IsWord32Sar(lhs_matcher, rhs_matcher);
59 }
60
61
62 Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
63 const Matcher<Node*>& rhs_matcher) {
64 return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
65 : IsWord32Or(lhs_matcher, rhs_matcher);
66 }
67
68
69 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
70 const Matcher<LoadRepresentation>& rep_matcher,
71 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) {
72 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _);
73 }
74
75
76 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
77 const Matcher<StoreRepresentation>& rep_matcher,
78 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
79 const Matcher<Node*>& value_matcher) {
80 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher,
81 value_matcher, _, _);
82 }
83
84
85 Matcher<Node*>
86 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand(
87 int offset) {
88 return IsLoad(
89 MachineType::Uint8(),
90 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
91 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
92 IsInt32Constant(offset)));
93 }
94
95
96 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
97 IsBytecodeOperandSignExtended(int offset) {
98 Matcher<Node*> load_matcher = IsLoad(
99 MachineType::Int8(),
100 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
101 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
102 IsInt32Constant(offset)));
103 if (kPointerSize == 8) {
104 load_matcher = IsChangeInt32ToInt64(load_matcher);
105 }
106 return load_matcher;
107 }
108
109
110 Matcher<Node*>
111 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort(
112 int offset) {
113 if (TargetSupportsUnalignedAccess()) {
114 return IsLoad(
115 MachineType::Uint16(),
116 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
117 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
118 IsInt32Constant(offset)));
119 } else {
120 Matcher<Node*> first_byte = IsLoad(
121 MachineType::Uint8(),
122 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
123 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
124 IsInt32Constant(offset)));
125 Matcher<Node*> second_byte = IsLoad(
126 MachineType::Uint8(),
127 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
128 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
129 IsInt32Constant(offset + 1)));
130 #if V8_TARGET_LITTLE_ENDIAN
131 return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)),
132 first_byte);
133 #elif V8_TARGET_BIG_ENDIAN
134 return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)),
135 second_byte);
136 #else
137 #error "Unknown Architecture"
138 #endif
139 }
140 }
141
142
143 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
144 IsBytecodeOperandShortSignExtended(int offset) {
145 Matcher<Node*> load_matcher;
146 if (TargetSupportsUnalignedAccess()) {
147 load_matcher = IsLoad(
148 MachineType::Int16(),
149 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
150 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
151 IsInt32Constant(offset)));
152 } else {
153 #if V8_TARGET_LITTLE_ENDIAN
154 int hi_byte_offset = offset + 1;
155 int lo_byte_offset = offset;
156
157 #elif V8_TARGET_BIG_ENDIAN
158 int hi_byte_offset = offset;
159 int lo_byte_offset = offset + 1;
160 #else
161 #error "Unknown Architecture"
162 #endif
163 Matcher<Node*> hi_byte = IsLoad(
164 MachineType::Int8(),
165 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
166 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
167 IsInt32Constant(hi_byte_offset)));
168 hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte));
169 Matcher<Node*> lo_byte = IsLoad(
170 MachineType::Uint8(),
171 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
172 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
173 IsInt32Constant(lo_byte_offset)));
174 load_matcher = IsWord32Or(hi_byte, lo_byte);
175 }
176
177 if (kPointerSize == 8) {
178 load_matcher = IsChangeInt32ToInt64(load_matcher);
179 }
180 return load_matcher;
181 }
182
183
184 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
185 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
186 InterpreterAssemblerForTest m(this, bytecode);
187 m.Dispatch();
188 Graph* graph = m.graph();
189
190 Node* end = graph->end();
191 EXPECT_EQ(1, end->InputCount());
192 Node* tail_call_node = end->InputAt(0);
193
194 Matcher<Node*> next_bytecode_offset_matcher =
195 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
196 IsInt32Constant(interpreter::Bytecodes::Size(bytecode)));
197 Matcher<Node*> target_bytecode_matcher =
198 m.IsLoad(MachineType::Uint8(),
199 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
200 next_bytecode_offset_matcher);
201 Matcher<Node*> code_target_matcher =
202 m.IsLoad(MachineType::Pointer(),
203 IsParameter(Linkage::kInterpreterDispatchTableParameter),
204 IsWord32Shl(target_bytecode_matcher,
205 IsInt32Constant(kPointerSizeLog2)));
206
207 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
208 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
209 EXPECT_THAT(
210 tail_call_node,
211 IsTailCall(m.call_descriptor(), code_target_matcher,
212 IsParameter(Linkage::kInterpreterAccumulatorParameter),
213 IsParameter(Linkage::kInterpreterRegisterFileParameter),
214 next_bytecode_offset_matcher,
215 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
216 IsParameter(Linkage::kInterpreterDispatchTableParameter),
217 IsParameter(Linkage::kInterpreterContextParameter), _, _));
218 }
219 }
220
221
222 TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
223 int jump_offsets[] = {-9710, -77, 0, +3, +97109};
224 TRACED_FOREACH(int, jump_offset, jump_offsets) {
225 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
226 InterpreterAssemblerForTest m(this, bytecode);
227 m.Jump(m.Int32Constant(jump_offset));
228 Graph* graph = m.graph();
229 Node* end = graph->end();
230 EXPECT_EQ(1, end->InputCount());
231 Node* tail_call_node = end->InputAt(0);
232
233 Matcher<Node*> next_bytecode_offset_matcher =
234 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
235 IsInt32Constant(jump_offset));
236 Matcher<Node*> target_bytecode_matcher =
237 m.IsLoad(MachineType::Uint8(),
238 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
239 next_bytecode_offset_matcher);
240 Matcher<Node*> code_target_matcher =
241 m.IsLoad(MachineType::Pointer(),
242 IsParameter(Linkage::kInterpreterDispatchTableParameter),
243 IsWord32Shl(target_bytecode_matcher,
244 IsInt32Constant(kPointerSizeLog2)));
245
246 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
247 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
248 EXPECT_THAT(
249 tail_call_node,
250 IsTailCall(m.call_descriptor(), code_target_matcher,
251 IsParameter(Linkage::kInterpreterAccumulatorParameter),
252 IsParameter(Linkage::kInterpreterRegisterFileParameter),
253 next_bytecode_offset_matcher,
254 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
255 IsParameter(Linkage::kInterpreterDispatchTableParameter),
256 IsParameter(Linkage::kInterpreterContextParameter), _, _));
257 }
258 }
259 }
260
261
262 TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
263 static const int kJumpIfTrueOffset = 73;
264
265 MachineOperatorBuilder machine(zone());
266
267 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
268 InterpreterAssemblerForTest m(this, bytecode);
269 Node* lhs = m.IntPtrConstant(0);
270 Node* rhs = m.IntPtrConstant(1);
271 m.JumpIfWordEqual(lhs, rhs, m.Int32Constant(kJumpIfTrueOffset));
272 Graph* graph = m.graph();
273 Node* end = graph->end();
274 EXPECT_EQ(2, end->InputCount());
275
276 int jump_offsets[] = {kJumpIfTrueOffset,
277 interpreter::Bytecodes::Size(bytecode)};
278 for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) {
279 Matcher<Node*> next_bytecode_offset_matcher =
280 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
281 IsInt32Constant(jump_offsets[i]));
282 Matcher<Node*> target_bytecode_matcher =
283 m.IsLoad(MachineType::Uint8(),
284 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
285 next_bytecode_offset_matcher);
286 Matcher<Node*> code_target_matcher =
287 m.IsLoad(MachineType::Pointer(),
288 IsParameter(Linkage::kInterpreterDispatchTableParameter),
289 IsWord32Shl(target_bytecode_matcher,
290 IsInt32Constant(kPointerSizeLog2)));
291 EXPECT_THAT(
292 end->InputAt(i),
293 IsTailCall(m.call_descriptor(), code_target_matcher,
294 IsParameter(Linkage::kInterpreterAccumulatorParameter),
295 IsParameter(Linkage::kInterpreterRegisterFileParameter),
296 next_bytecode_offset_matcher,
297 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
298 IsParameter(Linkage::kInterpreterDispatchTableParameter),
299 IsParameter(Linkage::kInterpreterContextParameter), _, _));
300 }
301
302 // TODO(oth): test control flow paths.
303 }
304 }
305
306
307 TARGET_TEST_F(InterpreterAssemblerTest, Return) {
308 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
309 InterpreterAssemblerForTest m(this, bytecode);
310 m.Return();
311 Graph* graph = m.graph();
312
313 Node* end = graph->end();
314 EXPECT_EQ(1, end->InputCount());
315 Node* tail_call_node = end->InputAt(0);
316
317 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
318 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
319 Handle<HeapObject> exit_trampoline =
320 isolate()->builtins()->InterpreterExitTrampoline();
321 EXPECT_THAT(
322 tail_call_node,
323 IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline),
324 IsParameter(Linkage::kInterpreterAccumulatorParameter),
325 IsParameter(Linkage::kInterpreterRegisterFileParameter),
326 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
327 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
328 IsParameter(Linkage::kInterpreterDispatchTableParameter),
329 IsParameter(Linkage::kInterpreterContextParameter), _, _));
330 }
331 }
332
333
334 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
335 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
336 InterpreterAssemblerForTest m(this, bytecode);
337 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode);
338 for (int i = 0; i < number_of_operands; i++) {
339 int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i);
340 switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
341 case interpreter::OperandType::kRegCount8:
342 EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset));
343 break;
344 case interpreter::OperandType::kIdx8:
345 EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(offset));
346 break;
347 case interpreter::OperandType::kImm8:
348 EXPECT_THAT(m.BytecodeOperandImm(i),
349 m.IsBytecodeOperandSignExtended(offset));
350 break;
351 case interpreter::OperandType::kMaybeReg8:
352 case interpreter::OperandType::kReg8:
353 case interpreter::OperandType::kRegOut8:
354 case interpreter::OperandType::kRegOutPair8:
355 case interpreter::OperandType::kRegOutTriple8:
356 case interpreter::OperandType::kRegPair8:
357 EXPECT_THAT(m.BytecodeOperandReg(i),
358 m.IsBytecodeOperandSignExtended(offset));
359 break;
360 case interpreter::OperandType::kRegCount16:
361 EXPECT_THAT(m.BytecodeOperandCount(i),
362 m.IsBytecodeOperandShort(offset));
363 break;
364 case interpreter::OperandType::kIdx16:
365 EXPECT_THAT(m.BytecodeOperandIdx(i),
366 m.IsBytecodeOperandShort(offset));
367 break;
368 case interpreter::OperandType::kMaybeReg16:
369 case interpreter::OperandType::kReg16:
370 case interpreter::OperandType::kRegOut16:
371 case interpreter::OperandType::kRegOutPair16:
372 case interpreter::OperandType::kRegOutTriple16:
373 case interpreter::OperandType::kRegPair16:
374 EXPECT_THAT(m.BytecodeOperandReg(i),
375 m.IsBytecodeOperandShortSignExtended(offset));
376 break;
377 case interpreter::OperandType::kNone:
378 UNREACHABLE();
379 break;
380 }
381 }
382 }
383 }
384
385
386 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
387 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
388 InterpreterAssemblerForTest m(this, bytecode);
389 // Should be incoming accumulator if not set.
390 EXPECT_THAT(m.GetAccumulator(),
391 IsParameter(Linkage::kInterpreterAccumulatorParameter));
392
393 // Should be set by SedtAccumulator.
394 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef);
395 m.SetAccumulator(accumulator_value_1);
396 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1);
397 Node* accumulator_value_2 = m.Int32Constant(42);
398 m.SetAccumulator(accumulator_value_2);
399 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2);
400
401 // Should be passed to next bytecode handler on dispatch.
402 m.Dispatch();
403 Graph* graph = m.graph();
404
405 Node* end = graph->end();
406 EXPECT_EQ(1, end->InputCount());
407 Node* tail_call_node = end->InputAt(0);
408
409 EXPECT_THAT(tail_call_node,
410 IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _,
411 _, _, _));
412 }
413 }
414
415
416 TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
417 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
418 InterpreterAssemblerForTest m(this, bytecode);
419 Node* context_node = m.Int32Constant(100);
420 m.SetContext(context_node);
421 EXPECT_THAT(m.GetContext(), context_node);
422 }
423 }
424
425
426 TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
427 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
428 InterpreterAssemblerForTest m(this, bytecode);
429 Node* reg_index_node = m.Int32Constant(44);
430 Node* reg_location_node = m.RegisterLocation(reg_index_node);
431 EXPECT_THAT(
432 reg_location_node,
433 IsIntPtrAdd(
434 IsParameter(Linkage::kInterpreterRegisterFileParameter),
435 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
436 }
437 }
438
439
440 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
441 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
442 InterpreterAssemblerForTest m(this, bytecode);
443 Node* reg_index_node = m.Int32Constant(44);
444 Node* load_reg_node = m.LoadRegister(reg_index_node);
445 EXPECT_THAT(
446 load_reg_node,
447 m.IsLoad(MachineType::AnyTagged(),
448 IsParameter(Linkage::kInterpreterRegisterFileParameter),
449 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
450 }
451 }
452
453
454 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
455 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
456 InterpreterAssemblerForTest m(this, bytecode);
457 Node* store_value = m.Int32Constant(0xdeadbeef);
458 Node* reg_index_node = m.Int32Constant(44);
459 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node);
460 EXPECT_THAT(
461 store_reg_node,
462 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged,
463 kNoWriteBarrier),
464 IsParameter(Linkage::kInterpreterRegisterFileParameter),
465 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)),
466 store_value));
467 }
468 }
469
470
471 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
472 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
473 InterpreterAssemblerForTest m(this, bytecode);
474 Node* value = m.Int32Constant(44);
475 EXPECT_THAT(m.SmiTag(value),
476 IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize)));
477 EXPECT_THAT(m.SmiUntag(value),
478 IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize)));
479 }
480 }
481
482
483 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
484 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
485 InterpreterAssemblerForTest m(this, bytecode);
486 Node* a = m.Int32Constant(0);
487 Node* b = m.Int32Constant(1);
488 Node* add = m.IntPtrAdd(a, b);
489 EXPECT_THAT(add, IsIntPtrAdd(a, b));
490 }
491 }
492
493
494 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
495 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
496 InterpreterAssemblerForTest m(this, bytecode);
497 Node* a = m.Int32Constant(0);
498 Node* b = m.Int32Constant(1);
499 Node* add = m.IntPtrSub(a, b);
500 EXPECT_THAT(add, IsIntPtrSub(a, b));
501 }
502 }
503
504
505 TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
506 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
507 InterpreterAssemblerForTest m(this, bytecode);
508 Node* a = m.Int32Constant(0);
509 Node* add = m.WordShl(a, 10);
510 EXPECT_THAT(add, IsWordShl(a, IsInt32Constant(10)));
511 }
512 }
513
514
515 TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
516 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
517 InterpreterAssemblerForTest m(this, bytecode);
518 Node* index = m.Int32Constant(2);
519 Node* load_constant = m.LoadConstantPoolEntry(index);
520 Matcher<Node*> constant_pool_matcher = m.IsLoad(
521 MachineType::AnyTagged(),
522 IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
523 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag));
524 EXPECT_THAT(
525 load_constant,
526 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher,
527 IsIntPtrAdd(
528 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
529 IsWordShl(index, IsInt32Constant(kPointerSizeLog2)))));
530 }
531 }
532
533
534 TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) {
535 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
536 InterpreterAssemblerForTest m(this, bytecode);
537 int index = 3;
538 Node* fixed_array = m.IntPtrConstant(0xdeadbeef);
539 Node* load_element = m.LoadFixedArrayElement(fixed_array, index);
540 EXPECT_THAT(
541 load_element,
542 m.IsLoad(MachineType::AnyTagged(), fixed_array,
543 IsIntPtrAdd(
544 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
545 IsWordShl(IsInt32Constant(index),
546 IsInt32Constant(kPointerSizeLog2)))));
547 }
548 }
549
550
551 TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
552 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
553 InterpreterAssemblerForTest m(this, bytecode);
554 Node* object = m.IntPtrConstant(0xdeadbeef);
555 int offset = 16;
556 Node* load_field = m.LoadObjectField(object, offset);
557 EXPECT_THAT(load_field,
558 m.IsLoad(MachineType::AnyTagged(), object,
559 IsIntPtrConstant(offset - kHeapObjectTag)));
560 }
561 }
562
563
564 TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
565 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
566 InterpreterAssemblerForTest m(this, bytecode);
567 Node* context = m.Int32Constant(1);
568 Node* slot_index = m.Int32Constant(22);
569 Node* load_context_slot = m.LoadContextSlot(context, slot_index);
570
571 Matcher<Node*> offset =
572 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
573 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
574 EXPECT_THAT(load_context_slot,
575 m.IsLoad(MachineType::AnyTagged(), context, offset));
576 }
577 }
578
579
580 TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
581 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
582 InterpreterAssemblerForTest m(this, bytecode);
583 Node* context = m.Int32Constant(1);
584 Node* slot_index = m.Int32Constant(22);
585 Node* value = m.Int32Constant(100);
586 Node* store_context_slot = m.StoreContextSlot(context, slot_index, value);
587
588 Matcher<Node*> offset =
589 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
590 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
591 EXPECT_THAT(store_context_slot,
592 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged,
593 kFullWriteBarrier),
594 context, offset, value));
595 }
596 }
597
598
599 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
600 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
601 InterpreterAssemblerForTest m(this, bytecode);
602 Node* arg1 = m.Int32Constant(2);
603 Node* arg2 = m.Int32Constant(3);
604 Node* call_runtime = m.CallRuntime(Runtime::kAdd, arg1, arg2);
605 EXPECT_THAT(
606 call_runtime,
607 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2),
608 IsParameter(Linkage::kInterpreterContextParameter), _, _));
609 }
610 }
611
612
613 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
614 const int kResultSizes[] = {1, 2};
615 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
616 TRACED_FOREACH(int, result_size, kResultSizes) {
617 InterpreterAssemblerForTest m(this, bytecode);
618 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size);
619
620 Node* function_id = m.Int32Constant(0);
621 Node* first_arg = m.Int32Constant(1);
622 Node* arg_count = m.Int32Constant(2);
623
624 Matcher<Node*> function_table = IsExternalConstant(
625 ExternalReference::runtime_function_table_address(isolate()));
626 Matcher<Node*> function = IsIntPtrAdd(
627 function_table,
628 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function))));
629 Matcher<Node*> function_entry =
630 m.IsLoad(MachineType::Pointer(), function,
631 IsInt32Constant(offsetof(Runtime::Function, entry)));
632
633 Node* call_runtime =
634 m.CallRuntime(function_id, first_arg, arg_count, result_size);
635 EXPECT_THAT(
636 call_runtime,
637 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
638 function_entry,
639 IsParameter(Linkage::kInterpreterContextParameter), _, _));
640 }
641 }
642 }
643
644
645 TARGET_TEST_F(InterpreterAssemblerTest, CallIC) {
646 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
647 InterpreterAssemblerForTest m(this, bytecode);
648 LoadWithVectorDescriptor descriptor(isolate());
649 Node* target = m.Int32Constant(1);
650 Node* arg1 = m.Int32Constant(2);
651 Node* arg2 = m.Int32Constant(3);
652 Node* arg3 = m.Int32Constant(4);
653 Node* arg4 = m.Int32Constant(5);
654 Node* call_ic = m.CallIC(descriptor, target, arg1, arg2, arg3, arg4);
655 EXPECT_THAT(
656 call_ic,
657 IsCall(_, target, arg1, arg2, arg3, arg4,
658 IsParameter(Linkage::kInterpreterContextParameter), _, _));
659 }
660 }
661
662
663 TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
664 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
665 InterpreterAssemblerForTest m(this, bytecode);
666 Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate());
667 Node* function = m.Int32Constant(0);
668 Node* first_arg = m.Int32Constant(1);
669 Node* arg_count = m.Int32Constant(2);
670 Node* call_js = m.CallJS(function, first_arg, arg_count);
671 EXPECT_THAT(
672 call_js,
673 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
674 function, IsParameter(Linkage::kInterpreterContextParameter), _,
675 _));
676 }
677 }
678
679
680 TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) {
681 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
682 InterpreterAssemblerForTest m(this, bytecode);
683 Node* feedback_vector = m.LoadTypeFeedbackVector();
684
685 Matcher<Node*> load_function_matcher =
686 m.IsLoad(MachineType::AnyTagged(),
687 IsParameter(Linkage::kInterpreterRegisterFileParameter),
688 IsIntPtrConstant(
689 InterpreterFrameConstants::kFunctionFromRegisterPointer));
690 Matcher<Node*> load_shared_function_info_matcher =
691 m.IsLoad(MachineType::AnyTagged(), load_function_matcher,
692 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
693 kHeapObjectTag));
694
695 EXPECT_THAT(
696 feedback_vector,
697 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher,
698 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
699 kHeapObjectTag)));
700 }
701 }
702
703 } // namespace compiler
704 } // namespace internal
705 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/interpreter-assembler-unittest.h ('k') | test/unittests/interpreter/interpreter-assembler-unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698