| 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 |