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 "src/compiler/interpreter-assembler.h" | 5 #include "src/compiler/interpreter-assembler.h" |
6 | 6 |
7 #include <ostream> | 7 #include <ostream> |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
29 interpreter::Bytecode bytecode) | 29 interpreter::Bytecode bytecode) |
30 : bytecode_(bytecode), | 30 : bytecode_(bytecode), |
31 raw_assembler_(new RawMachineAssembler( | 31 raw_assembler_(new RawMachineAssembler( |
32 isolate, new (zone) Graph(zone), | 32 isolate, new (zone) Graph(zone), |
33 Linkage::GetInterpreterDispatchDescriptor(zone), | 33 Linkage::GetInterpreterDispatchDescriptor(zone), |
34 MachineType::PointerRepresentation(), | 34 MachineType::PointerRepresentation(), |
35 InstructionSelector::SupportedMachineOperatorFlags())), | 35 InstructionSelector::SupportedMachineOperatorFlags())), |
36 accumulator_( | 36 accumulator_( |
37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), |
| 38 bytecode_offset_(raw_assembler_->Parameter( |
| 39 Linkage::kInterpreterBytecodeOffsetParameter)), |
38 context_( | 40 context_( |
39 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 41 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), |
40 code_generated_(false) {} | 42 code_generated_(false) {} |
41 | 43 |
42 | 44 |
43 InterpreterAssembler::~InterpreterAssembler() {} | 45 InterpreterAssembler::~InterpreterAssembler() {} |
44 | 46 |
45 | 47 |
46 Handle<Code> InterpreterAssembler::GenerateCode() { | 48 Handle<Code> InterpreterAssembler::GenerateCode() { |
47 DCHECK(!code_generated_); | 49 DCHECK(!code_generated_); |
(...skipping 25 matching lines...) Expand all Loading... |
73 | 75 |
74 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 76 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } |
75 | 77 |
76 | 78 |
77 Node* InterpreterAssembler::GetContext() { return context_; } | 79 Node* InterpreterAssembler::GetContext() { return context_; } |
78 | 80 |
79 | 81 |
80 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } | 82 void InterpreterAssembler::SetContext(Node* value) { context_ = value; } |
81 | 83 |
82 | 84 |
| 85 Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; } |
| 86 |
| 87 |
83 Node* InterpreterAssembler::RegisterFileRawPointer() { | 88 Node* InterpreterAssembler::RegisterFileRawPointer() { |
84 return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); | 89 return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); |
85 } | 90 } |
86 | 91 |
87 | 92 |
88 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 93 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { |
89 return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); | 94 return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); |
90 } | 95 } |
91 | 96 |
92 | 97 |
93 Node* InterpreterAssembler::BytecodeOffset() { | |
94 return raw_assembler_->Parameter( | |
95 Linkage::kInterpreterBytecodeOffsetParameter); | |
96 } | |
97 | |
98 | |
99 Node* InterpreterAssembler::DispatchTableRawPointer() { | 98 Node* InterpreterAssembler::DispatchTableRawPointer() { |
100 return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); | 99 return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); |
101 } | 100 } |
102 | 101 |
103 | 102 |
| 103 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |
| 104 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |
| 105 } |
| 106 |
| 107 |
| 108 Node* InterpreterAssembler::LoadRegister(int offset) { |
| 109 return raw_assembler_->Load(MachineType::AnyTagged(), |
| 110 RegisterFileRawPointer(), Int32Constant(offset)); |
| 111 } |
| 112 |
| 113 |
| 114 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { |
| 115 return LoadRegister(reg.ToOperand() << kPointerSizeLog2); |
| 116 } |
| 117 |
| 118 |
104 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 119 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { |
105 return WordShl(index, kPointerSizeLog2); | 120 return WordShl(index, kPointerSizeLog2); |
106 } | 121 } |
107 | 122 |
108 | 123 |
109 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | |
110 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | |
111 } | |
112 | |
113 | |
114 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { | |
115 return raw_assembler_->Load( | |
116 MachineType::AnyTagged(), RegisterFileRawPointer(), | |
117 RegisterFrameOffset(Int32Constant(reg.ToOperand()))); | |
118 } | |
119 | |
120 | |
121 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 124 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { |
122 return raw_assembler_->Load(MachineType::AnyTagged(), | 125 return raw_assembler_->Load(MachineType::AnyTagged(), |
123 RegisterFileRawPointer(), | 126 RegisterFileRawPointer(), |
124 RegisterFrameOffset(reg_index)); | 127 RegisterFrameOffset(reg_index)); |
125 } | 128 } |
126 | 129 |
127 | 130 |
| 131 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { |
| 132 return raw_assembler_->Store(MachineRepresentation::kTagged, |
| 133 RegisterFileRawPointer(), Int32Constant(offset), |
| 134 value, kNoWriteBarrier); |
| 135 } |
| 136 |
| 137 |
| 138 Node* InterpreterAssembler::StoreRegister(Node* value, |
| 139 interpreter::Register reg) { |
| 140 return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); |
| 141 } |
| 142 |
| 143 |
128 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 144 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { |
129 return raw_assembler_->Store( | 145 return raw_assembler_->Store( |
130 MachineRepresentation::kTagged, RegisterFileRawPointer(), | 146 MachineRepresentation::kTagged, RegisterFileRawPointer(), |
131 RegisterFrameOffset(reg_index), value, kNoWriteBarrier); | 147 RegisterFrameOffset(reg_index), value, kNoWriteBarrier); |
132 } | 148 } |
133 | 149 |
134 | 150 |
135 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 151 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { |
136 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 152 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); |
137 DCHECK_EQ(interpreter::OperandSize::kByte, | 153 DCHECK_EQ(interpreter::OperandSize::kByte, |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 args[0] = arg_count; | 395 args[0] = arg_count; |
380 args[1] = new_target; | 396 args[1] = new_target; |
381 args[2] = constructor; | 397 args[2] = constructor; |
382 args[3] = first_arg; | 398 args[3] = first_arg; |
383 args[4] = GetContext(); | 399 args[4] = GetContext(); |
384 | 400 |
385 return CallN(descriptor, code_target, args); | 401 return CallN(descriptor, code_target, args); |
386 } | 402 } |
387 | 403 |
388 | 404 |
| 405 void InterpreterAssembler::CallPrologue() { |
| 406 StoreRegister(SmiTag(bytecode_offset_), |
| 407 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); |
| 408 } |
| 409 |
| 410 |
| 411 void InterpreterAssembler::CallEpilogue() { |
| 412 // Restore the bytecode offset from the stack frame. |
| 413 bytecode_offset_ = SmiUntag(LoadRegister( |
| 414 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer)); |
| 415 } |
| 416 |
| 417 |
389 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 418 Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, |
390 Node** args) { | 419 Node** args) { |
| 420 CallPrologue(); |
| 421 |
391 Node* stack_pointer_before_call = nullptr; | 422 Node* stack_pointer_before_call = nullptr; |
392 if (FLAG_debug_code) { | 423 if (FLAG_debug_code) { |
393 stack_pointer_before_call = raw_assembler_->LoadStackPointer(); | 424 stack_pointer_before_call = raw_assembler_->LoadStackPointer(); |
394 } | 425 } |
395 Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); | 426 Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); |
396 if (FLAG_debug_code) { | 427 if (FLAG_debug_code) { |
397 Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); | 428 Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); |
398 AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 429 AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, |
399 kUnexpectedStackPointer); | 430 kUnexpectedStackPointer); |
400 } | 431 } |
| 432 |
| 433 CallEpilogue(); |
401 return return_val; | 434 return return_val; |
402 } | 435 } |
403 | 436 |
404 | 437 |
405 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, | 438 Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, |
406 Node* arg_count) { | 439 Node* arg_count) { |
407 Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 440 Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); |
408 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 441 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( |
409 isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 442 isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); |
410 | 443 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 args[1] = first_arg; | 523 args[1] = first_arg; |
491 args[2] = function_entry; | 524 args[2] = function_entry; |
492 args[3] = GetContext(); | 525 args[3] = GetContext(); |
493 | 526 |
494 return CallN(descriptor, code_target, args); | 527 return CallN(descriptor, code_target, args); |
495 } | 528 } |
496 | 529 |
497 | 530 |
498 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 531 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, |
499 Node* arg1) { | 532 Node* arg1) { |
500 return raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); | 533 CallPrologue(); |
| 534 Node* return_val = |
| 535 raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); |
| 536 CallEpilogue(); |
| 537 return return_val; |
501 } | 538 } |
502 | 539 |
503 | 540 |
504 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 541 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, |
505 Node* arg1, Node* arg2) { | 542 Node* arg1, Node* arg2) { |
506 return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); | 543 CallPrologue(); |
| 544 Node* return_val = |
| 545 raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); |
| 546 CallEpilogue(); |
| 547 return return_val; |
507 } | 548 } |
508 | 549 |
509 | 550 |
510 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, | 551 Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, |
511 Node* arg1, Node* arg2, Node* arg3, | 552 Node* arg1, Node* arg2, Node* arg3, |
512 Node* arg4) { | 553 Node* arg4) { |
513 return raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, arg4, | 554 CallPrologue(); |
514 GetContext()); | 555 Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, |
| 556 arg4, GetContext()); |
| 557 CallEpilogue(); |
| 558 return return_val; |
515 } | 559 } |
516 | 560 |
517 | 561 |
518 void InterpreterAssembler::Return() { | 562 void InterpreterAssembler::Return() { |
519 Node* exit_trampoline_code_object = | 563 Node* exit_trampoline_code_object = |
520 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); | 564 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); |
521 // If the order of the parameters you need to change the call signature below. | 565 // If the order of the parameters you need to change the call signature below. |
522 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 566 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
523 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 567 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
524 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 568 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 new_bytecode_offset, | 632 new_bytecode_offset, |
589 BytecodeArrayTaggedPointer(), | 633 BytecodeArrayTaggedPointer(), |
590 DispatchTableRawPointer(), | 634 DispatchTableRawPointer(), |
591 GetContext() }; | 635 GetContext() }; |
592 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 636 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); |
593 } | 637 } |
594 | 638 |
595 | 639 |
596 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { | 640 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { |
597 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); | 641 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); |
598 CallRuntime(Runtime::kAbort, abort_id); | 642 Node* ret_value = CallRuntime(Runtime::kAbort, abort_id); |
599 Return(); | 643 // Unreached, but keeps turbofan happy. |
| 644 raw_assembler_->Return(ret_value); |
600 } | 645 } |
601 | 646 |
602 | 647 |
603 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, | 648 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, |
604 BailoutReason bailout_reason) { | 649 BailoutReason bailout_reason) { |
605 RawMachineLabel match, no_match; | 650 RawMachineLabel match, no_match; |
606 Node* condition = raw_assembler_->WordEqual(lhs, rhs); | 651 Node* condition = raw_assembler_->WordEqual(lhs, rhs); |
607 raw_assembler_->Branch(condition, &match, &no_match); | 652 raw_assembler_->Branch(condition, &match, &no_match); |
608 raw_assembler_->Bind(&no_match); | 653 raw_assembler_->Bind(&no_match); |
609 Abort(bailout_reason); | 654 Abort(bailout_reason); |
(...skipping 26 matching lines...) Expand all Loading... |
636 return raw_assembler_->call_descriptor(); | 681 return raw_assembler_->call_descriptor(); |
637 } | 682 } |
638 | 683 |
639 | 684 |
640 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 685 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
641 | 686 |
642 | 687 |
643 } // namespace compiler | 688 } // namespace compiler |
644 } // namespace internal | 689 } // namespace internal |
645 } // namespace v8 | 690 } // namespace v8 |
OLD | NEW |