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