| 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/interpreter/interpreter-assembler-unittest.h" | 5 #include "test/unittests/interpreter/interpreter-assembler-unittest.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
| 9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
| 10 #include "src/interface-descriptors.h" | 10 #include "src/interface-descriptors.h" |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 Matcher<Node*> code_target_matcher = m.IsLoad( | 335 Matcher<Node*> code_target_matcher = m.IsLoad( |
| 336 MachineType::Pointer(), | 336 MachineType::Pointer(), |
| 337 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 337 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 338 IsWordShl(target_bytecode_matcher, IsIntPtrConstant(kPointerSizeLog2))); | 338 IsWordShl(target_bytecode_matcher, IsIntPtrConstant(kPointerSizeLog2))); |
| 339 | 339 |
| 340 EXPECT_THAT( | 340 EXPECT_THAT( |
| 341 tail_call_node, | 341 tail_call_node, |
| 342 IsTailCall( | 342 IsTailCall( |
| 343 _, code_target_matcher, | 343 _, code_target_matcher, |
| 344 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 344 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
| 345 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | |
| 346 next_bytecode_offset_matcher, | 345 next_bytecode_offset_matcher, |
| 347 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 346 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
| 348 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 347 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 349 _, _)); | 348 _, _)); |
| 350 } | 349 } |
| 351 } | 350 } |
| 352 | 351 |
| 353 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { | 352 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { |
| 354 // If debug code is enabled we emit extra code in Jump. | 353 // If debug code is enabled we emit extra code in Jump. |
| 355 if (FLAG_debug_code) return; | 354 if (FLAG_debug_code) return; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 377 MachineType::Pointer(), | 376 MachineType::Pointer(), |
| 378 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 377 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 379 IsWordShl(target_bytecode_matcher, | 378 IsWordShl(target_bytecode_matcher, |
| 380 IsIntPtrConstant(kPointerSizeLog2))); | 379 IsIntPtrConstant(kPointerSizeLog2))); |
| 381 | 380 |
| 382 EXPECT_THAT( | 381 EXPECT_THAT( |
| 383 tail_call_node, | 382 tail_call_node, |
| 384 IsTailCall( | 383 IsTailCall( |
| 385 _, code_target_matcher, | 384 _, code_target_matcher, |
| 386 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 385 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
| 387 IsParameter( | |
| 388 InterpreterDispatchDescriptor::kRegisterFileParameter), | |
| 389 next_bytecode_offset_matcher, _, | 386 next_bytecode_offset_matcher, _, |
| 390 IsParameter( | 387 IsParameter( |
| 391 InterpreterDispatchDescriptor::kDispatchTableParameter), | 388 InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 392 _, _)); | 389 _, _)); |
| 393 } | 390 } |
| 394 } | 391 } |
| 395 } | 392 } |
| 396 | 393 |
| 397 TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { | 394 TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { |
| 398 static const int kJumpIfTrueOffset = 73; | 395 static const int kJumpIfTrueOffset = 73; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 427 Matcher<Node*> code_target_matcher = m.IsLoad( | 424 Matcher<Node*> code_target_matcher = m.IsLoad( |
| 428 MachineType::Pointer(), | 425 MachineType::Pointer(), |
| 429 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 426 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 430 IsWordShl(target_bytecode_matcher, | 427 IsWordShl(target_bytecode_matcher, |
| 431 IsIntPtrConstant(kPointerSizeLog2))); | 428 IsIntPtrConstant(kPointerSizeLog2))); |
| 432 EXPECT_THAT( | 429 EXPECT_THAT( |
| 433 end->InputAt(i), | 430 end->InputAt(i), |
| 434 IsTailCall( | 431 IsTailCall( |
| 435 _, code_target_matcher, | 432 _, code_target_matcher, |
| 436 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 433 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
| 437 IsParameter( | |
| 438 InterpreterDispatchDescriptor::kRegisterFileParameter), | |
| 439 next_bytecode_offset_matcher, _, | 434 next_bytecode_offset_matcher, _, |
| 440 IsParameter( | 435 IsParameter( |
| 441 InterpreterDispatchDescriptor::kDispatchTableParameter), | 436 InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 442 _, _)); | 437 _, _)); |
| 443 } | 438 } |
| 444 | 439 |
| 445 // TODO(oth): test control flow paths. | 440 // TODO(oth): test control flow paths. |
| 446 } | 441 } |
| 447 } | 442 } |
| 448 | 443 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 462 Handle<HeapObject> exit_trampoline = | 457 Handle<HeapObject> exit_trampoline = |
| 463 isolate()->builtins()->InterpreterExitTrampoline(); | 458 isolate()->builtins()->InterpreterExitTrampoline(); |
| 464 Matcher<Node*> exit_trampoline_entry_matcher = | 459 Matcher<Node*> exit_trampoline_entry_matcher = |
| 465 IsIntPtrAdd(IsHeapConstant(exit_trampoline), | 460 IsIntPtrAdd(IsHeapConstant(exit_trampoline), |
| 466 IsIntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 461 IsIntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); |
| 467 EXPECT_THAT( | 462 EXPECT_THAT( |
| 468 tail_call_node, | 463 tail_call_node, |
| 469 IsTailCall( | 464 IsTailCall( |
| 470 _, exit_trampoline_entry_matcher, | 465 _, exit_trampoline_entry_matcher, |
| 471 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 466 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
| 472 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | |
| 473 IsParameter( | 467 IsParameter( |
| 474 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | 468 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 475 _, | 469 _, |
| 476 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 470 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 477 _, _)); | 471 _, _)); |
| 478 } | 472 } |
| 479 } | 473 } |
| 480 | 474 |
| 481 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { | 475 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
| 482 static const OperandScale kOperandScales[] = { | 476 static const OperandScale kOperandScales[] = { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 | 549 |
| 556 // Should be passed to next bytecode handler on dispatch. | 550 // Should be passed to next bytecode handler on dispatch. |
| 557 m.Dispatch(); | 551 m.Dispatch(); |
| 558 Graph* graph = m.graph(); | 552 Graph* graph = m.graph(); |
| 559 | 553 |
| 560 Node* end = graph->end(); | 554 Node* end = graph->end(); |
| 561 EXPECT_EQ(1, end->InputCount()); | 555 EXPECT_EQ(1, end->InputCount()); |
| 562 Node* tail_call_node = end->InputAt(0); | 556 Node* tail_call_node = end->InputAt(0); |
| 563 | 557 |
| 564 EXPECT_THAT(tail_call_node, | 558 EXPECT_THAT(tail_call_node, |
| 565 IsTailCall(_, _, accumulator_value_2, _, _, _, _, _, _)); | 559 IsTailCall(_, _, accumulator_value_2, _, _, _, _)); |
| 566 } | 560 } |
| 567 } | 561 } |
| 568 | 562 |
| 569 TARGET_TEST_F(InterpreterAssemblerTest, GetContext) { | 563 TARGET_TEST_F(InterpreterAssemblerTest, GetContext) { |
| 570 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 564 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 571 InterpreterAssemblerForTest m(this, bytecode); | 565 InterpreterAssemblerForTest m(this, bytecode); |
| 572 EXPECT_THAT( | 566 EXPECT_THAT( |
| 573 m.GetContext(), | 567 m.GetContext(), |
| 574 m.IsLoad( | 568 m.IsLoad(MachineType::AnyTagged(), IsLoadParentFramePointer(), |
| 575 MachineType::AnyTagged(), | 569 IsIntPtrConstant(Register::current_context().ToOperand() |
| 576 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | 570 << kPointerSizeLog2))); |
| 577 IsIntPtrConstant(-Register::current_context().index() | |
| 578 << kPointerSizeLog2))); | |
| 579 } | 571 } |
| 580 } | 572 } |
| 581 | 573 |
| 582 TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { | 574 TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { |
| 583 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 575 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 584 InterpreterAssemblerForTest m(this, bytecode); | 576 InterpreterAssemblerForTest m(this, bytecode); |
| 585 Node* reg_index_node = m.IntPtrConstant(44); | 577 Node* reg_index_node = m.IntPtrConstant(44); |
| 586 Node* reg_location_node = m.RegisterLocation(reg_index_node); | 578 Node* reg_location_node = m.RegisterLocation(reg_index_node); |
| 587 EXPECT_THAT( | 579 EXPECT_THAT(reg_location_node, |
| 588 reg_location_node, | 580 IsIntPtrAdd(IsLoadParentFramePointer(), |
| 589 IsIntPtrAdd( | 581 IsWordShl(reg_index_node, |
| 590 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | 582 IsIntPtrConstant(kPointerSizeLog2)))); |
| 591 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)))); | |
| 592 } | 583 } |
| 593 } | 584 } |
| 594 | 585 |
| 595 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { | 586 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { |
| 596 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 587 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 597 InterpreterAssemblerForTest m(this, bytecode); | 588 InterpreterAssemblerForTest m(this, bytecode); |
| 598 Node* reg_index_node = m.IntPtrConstant(44); | 589 Node* reg_index_node = m.IntPtrConstant(44); |
| 599 Node* load_reg_node = m.LoadRegister(reg_index_node); | 590 Node* load_reg_node = m.LoadRegister(reg_index_node); |
| 600 EXPECT_THAT( | 591 EXPECT_THAT(load_reg_node, |
| 601 load_reg_node, | 592 m.IsLoad(MachineType::AnyTagged(), IsLoadParentFramePointer(), |
| 602 m.IsLoad( | 593 IsWordShl(reg_index_node, |
| 603 MachineType::AnyTagged(), | 594 IsIntPtrConstant(kPointerSizeLog2)))); |
| 604 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | |
| 605 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)))); | |
| 606 } | 595 } |
| 607 } | 596 } |
| 608 | 597 |
| 609 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { | 598 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { |
| 610 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 599 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 611 InterpreterAssemblerForTest m(this, bytecode); | 600 InterpreterAssemblerForTest m(this, bytecode); |
| 612 Node* store_value = m.Int32Constant(0xdeadbeef); | 601 Node* store_value = m.Int32Constant(0xdeadbeef); |
| 613 Node* reg_index_node = m.IntPtrConstant(44); | 602 Node* reg_index_node = m.IntPtrConstant(44); |
| 614 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); | 603 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); |
| 615 EXPECT_THAT( | 604 EXPECT_THAT( |
| 616 store_reg_node, | 605 store_reg_node, |
| 617 m.IsStore( | 606 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged, |
| 618 StoreRepresentation(MachineRepresentation::kTagged, | 607 kNoWriteBarrier), |
| 619 kNoWriteBarrier), | 608 IsLoadParentFramePointer(), |
| 620 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | 609 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)), |
| 621 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)), | 610 store_value)); |
| 622 store_value)); | |
| 623 } | 611 } |
| 624 } | 612 } |
| 625 | 613 |
| 626 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { | 614 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { |
| 627 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 615 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 628 InterpreterAssemblerForTest m(this, bytecode); | 616 InterpreterAssemblerForTest m(this, bytecode); |
| 629 Node* value = m.Int32Constant(44); | 617 Node* value = m.Int32Constant(44); |
| 630 EXPECT_THAT( | 618 EXPECT_THAT( |
| 631 m.SmiTag(value), | 619 m.SmiTag(value), |
| 632 IsWordShl(value, IsIntPtrConstant(kSmiShiftSize + kSmiTagSize))); | 620 IsWordShl(value, IsIntPtrConstant(kSmiShiftSize + kSmiTagSize))); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 kFullWriteBarrier), | 714 kFullWriteBarrier), |
| 727 context, offset, value)); | 715 context, offset, value)); |
| 728 } | 716 } |
| 729 } | 717 } |
| 730 | 718 |
| 731 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { | 719 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { |
| 732 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 720 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 733 InterpreterAssemblerForTest m(this, bytecode); | 721 InterpreterAssemblerForTest m(this, bytecode); |
| 734 Node* arg1 = m.Int32Constant(2); | 722 Node* arg1 = m.Int32Constant(2); |
| 735 Node* arg2 = m.Int32Constant(3); | 723 Node* arg2 = m.Int32Constant(3); |
| 736 Node* context = | 724 Node* context = m.Int32Constant(4); |
| 737 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); | |
| 738 Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2); | 725 Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2); |
| 739 EXPECT_THAT( | 726 EXPECT_THAT(call_runtime, |
| 740 call_runtime, | 727 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), context, _, _)); |
| 741 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), | |
| 742 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, | |
| 743 _)); | |
| 744 } | 728 } |
| 745 } | 729 } |
| 746 | 730 |
| 747 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { | 731 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { |
| 748 const int kResultSizes[] = {1, 2}; | 732 const int kResultSizes[] = {1, 2}; |
| 749 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 733 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 750 TRACED_FOREACH(int, result_size, kResultSizes) { | 734 TRACED_FOREACH(int, result_size, kResultSizes) { |
| 751 InterpreterAssemblerForTest m(this, bytecode); | 735 InterpreterAssemblerForTest m(this, bytecode); |
| 752 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size); | 736 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size); |
| 753 | 737 |
| 754 Node* function_id = m.Int32Constant(0); | 738 Node* function_id = m.Int32Constant(0); |
| 755 Node* first_arg = m.Int32Constant(1); | 739 Node* first_arg = m.Int32Constant(1); |
| 756 Node* arg_count = m.Int32Constant(2); | 740 Node* arg_count = m.Int32Constant(2); |
| 757 Node* context = | 741 Node* context = m.Int32Constant(4); |
| 758 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); | |
| 759 | 742 |
| 760 Matcher<Node*> function_table = IsExternalConstant( | 743 Matcher<Node*> function_table = IsExternalConstant( |
| 761 ExternalReference::runtime_function_table_address(isolate())); | 744 ExternalReference::runtime_function_table_address(isolate())); |
| 762 Matcher<Node*> function = IsIntPtrAdd( | 745 Matcher<Node*> function = IsIntPtrAdd( |
| 763 function_table, | 746 function_table, |
| 764 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function)))); | 747 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function)))); |
| 765 Matcher<Node*> function_entry = | 748 Matcher<Node*> function_entry = |
| 766 m.IsLoad(MachineType::Pointer(), function, | 749 m.IsLoad(MachineType::Pointer(), function, |
| 767 IsIntPtrConstant(offsetof(Runtime::Function, entry))); | 750 IsIntPtrConstant(offsetof(Runtime::Function, entry))); |
| 768 | 751 |
| 769 Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg, | 752 Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg, |
| 770 arg_count, result_size); | 753 arg_count, result_size); |
| 771 EXPECT_THAT( | 754 EXPECT_THAT(call_runtime, |
| 772 call_runtime, | 755 IsCall(_, IsHeapConstant(builtin.code()), arg_count, |
| 773 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, | 756 first_arg, function_entry, context, _, _)); |
| 774 function_entry, | |
| 775 IsParameter(InterpreterDispatchDescriptor::kContextParameter), | |
| 776 _, _)); | |
| 777 } | 757 } |
| 778 } | 758 } |
| 779 } | 759 } |
| 780 | 760 |
| 781 TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { | 761 TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { |
| 782 TailCallMode tail_call_modes[] = {TailCallMode::kDisallow, | 762 TailCallMode tail_call_modes[] = {TailCallMode::kDisallow, |
| 783 TailCallMode::kAllow}; | 763 TailCallMode::kAllow}; |
| 784 TRACED_FOREACH(TailCallMode, tail_call_mode, tail_call_modes) { | 764 TRACED_FOREACH(TailCallMode, tail_call_mode, tail_call_modes) { |
| 785 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 765 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 786 InterpreterAssemblerForTest m(this, bytecode); | 766 InterpreterAssemblerForTest m(this, bytecode); |
| 787 Callable builtin = | 767 Callable builtin = |
| 788 CodeFactory::InterpreterPushArgsAndCall(isolate(), tail_call_mode); | 768 CodeFactory::InterpreterPushArgsAndCall(isolate(), tail_call_mode); |
| 789 Node* function = m.Int32Constant(0); | 769 Node* function = m.Int32Constant(0); |
| 790 Node* first_arg = m.Int32Constant(1); | 770 Node* first_arg = m.Int32Constant(1); |
| 791 Node* arg_count = m.Int32Constant(2); | 771 Node* arg_count = m.Int32Constant(2); |
| 792 Node* context = | 772 Node* context = m.Int32Constant(3); |
| 793 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); | |
| 794 Node* call_js = | 773 Node* call_js = |
| 795 m.CallJS(function, context, first_arg, arg_count, tail_call_mode); | 774 m.CallJS(function, context, first_arg, arg_count, tail_call_mode); |
| 796 EXPECT_THAT( | 775 EXPECT_THAT(call_js, IsCall(_, IsHeapConstant(builtin.code()), arg_count, |
| 797 call_js, | 776 first_arg, function, context, _, _)); |
| 798 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, | |
| 799 function, | |
| 800 IsParameter(InterpreterDispatchDescriptor::kContextParameter), | |
| 801 _, _)); | |
| 802 } | 777 } |
| 803 } | 778 } |
| 804 } | 779 } |
| 805 | 780 |
| 806 TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { | 781 TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { |
| 807 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 782 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 808 InterpreterAssemblerForTest m(this, bytecode); | 783 InterpreterAssemblerForTest m(this, bytecode); |
| 809 Node* feedback_vector = m.LoadTypeFeedbackVector(); | 784 Node* feedback_vector = m.LoadTypeFeedbackVector(); |
| 810 | 785 |
| 811 Matcher<Node*> load_function_matcher = m.IsLoad( | 786 Matcher<Node*> load_function_matcher = |
| 812 MachineType::AnyTagged(), | 787 m.IsLoad(MachineType::AnyTagged(), IsLoadParentFramePointer(), |
| 813 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), | 788 IsIntPtrConstant(Register::function_closure().ToOperand() |
| 814 IsIntPtrConstant( | 789 << kPointerSizeLog2)); |
| 815 InterpreterFrameConstants::kFunctionFromRegisterPointer)); | |
| 816 Matcher<Node*> load_shared_function_info_matcher = | 790 Matcher<Node*> load_shared_function_info_matcher = |
| 817 m.IsLoad(MachineType::AnyTagged(), load_function_matcher, | 791 m.IsLoad(MachineType::AnyTagged(), load_function_matcher, |
| 818 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset - | 792 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset - |
| 819 kHeapObjectTag)); | 793 kHeapObjectTag)); |
| 820 | 794 |
| 821 EXPECT_THAT( | 795 EXPECT_THAT( |
| 822 feedback_vector, | 796 feedback_vector, |
| 823 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher, | 797 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher, |
| 824 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset - | 798 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset - |
| 825 kHeapObjectTag))); | 799 kHeapObjectTag))); |
| 826 } | 800 } |
| 827 } | 801 } |
| 828 | 802 |
| 829 } // namespace interpreter | 803 } // namespace interpreter |
| 830 } // namespace internal | 804 } // namespace internal |
| 831 } // namespace v8 | 805 } // namespace v8 |
| OLD | NEW |