| 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/interpreter/interpreter-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <ostream> | 8 #include <ostream> |
| 9 | 9 |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 70 } |
| 71 | 71 |
| 72 void InterpreterAssembler::SetContext(Node* value) { | 72 void InterpreterAssembler::SetContext(Node* value) { |
| 73 StoreRegister(value, Register::current_context()); | 73 StoreRegister(value, Register::current_context()); |
| 74 } | 74 } |
| 75 | 75 |
| 76 Node* InterpreterAssembler::BytecodeOffset() { | 76 Node* InterpreterAssembler::BytecodeOffset() { |
| 77 return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter); | 77 return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter); |
| 78 } | 78 } |
| 79 | 79 |
| 80 Node* InterpreterAssembler::RegisterFileRawPointer() { | |
| 81 return Parameter(InterpreterDispatchDescriptor::kRegisterFileParameter); | |
| 82 } | |
| 83 | |
| 84 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 80 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { |
| 85 if (made_call_) { | 81 if (made_call_) { |
| 86 // If we have made a call, restore bytecode array from stack frame in case | 82 // If we have made a call, restore bytecode array from stack frame in case |
| 87 // the debugger has swapped us to the patched debugger bytecode array. | 83 // the debugger has swapped us to the patched debugger bytecode array. |
| 88 return LoadRegister( | 84 return LoadRegister(Register::bytecode_array()); |
| 89 InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer); | |
| 90 } else { | 85 } else { |
| 91 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); | 86 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); |
| 92 } | 87 } |
| 93 } | 88 } |
| 94 | 89 |
| 95 Node* InterpreterAssembler::DispatchTableRawPointer() { | 90 Node* InterpreterAssembler::DispatchTableRawPointer() { |
| 96 return Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter); | 91 return Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter); |
| 97 } | 92 } |
| 98 | 93 |
| 99 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 94 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |
| 100 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 95 return IntPtrAdd(LoadParentFramePointer(), RegisterFrameOffset(reg_index)); |
| 101 } | |
| 102 | |
| 103 Node* InterpreterAssembler::LoadRegister(int offset) { | |
| 104 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), | |
| 105 IntPtrConstant(offset)); | |
| 106 } | |
| 107 | |
| 108 Node* InterpreterAssembler::LoadRegister(Register reg) { | |
| 109 return LoadRegister(-reg.index() << kPointerSizeLog2); | |
| 110 } | 96 } |
| 111 | 97 |
| 112 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { | 98 Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { |
| 113 return WordShl(index, kPointerSizeLog2); | 99 return WordShl(index, kPointerSizeLog2); |
| 114 } | 100 } |
| 115 | 101 |
| 102 Node* InterpreterAssembler::LoadRegister(Register reg) { |
| 103 return Load(MachineType::AnyTagged(), LoadParentFramePointer(), |
| 104 IntPtrConstant(reg.ToOperand() << kPointerSizeLog2)); |
| 105 } |
| 106 |
| 116 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 107 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { |
| 117 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), | 108 return Load(MachineType::AnyTagged(), LoadParentFramePointer(), |
| 118 RegisterFrameOffset(reg_index)); | 109 RegisterFrameOffset(reg_index)); |
| 119 } | 110 } |
| 120 | 111 |
| 121 Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { | |
| 122 return StoreNoWriteBarrier(MachineRepresentation::kTagged, | |
| 123 RegisterFileRawPointer(), IntPtrConstant(offset), | |
| 124 value); | |
| 125 } | |
| 126 | |
| 127 Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) { | 112 Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) { |
| 128 return StoreRegister(value, IntPtrConstant(-reg.index())); | 113 return StoreNoWriteBarrier( |
| 114 MachineRepresentation::kTagged, LoadParentFramePointer(), |
| 115 IntPtrConstant(reg.ToOperand() << kPointerSizeLog2), value); |
| 129 } | 116 } |
| 130 | 117 |
| 131 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 118 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { |
| 132 return StoreNoWriteBarrier(MachineRepresentation::kTagged, | 119 return StoreNoWriteBarrier(MachineRepresentation::kTagged, |
| 133 RegisterFileRawPointer(), | 120 LoadParentFramePointer(), |
| 134 RegisterFrameOffset(reg_index), value); | 121 RegisterFrameOffset(reg_index), value); |
| 135 } | 122 } |
| 136 | 123 |
| 137 Node* InterpreterAssembler::NextRegister(Node* reg_index) { | 124 Node* InterpreterAssembler::NextRegister(Node* reg_index) { |
| 138 // Register indexes are negative, so the next index is minus one. | 125 // Register indexes are negative, so the next index is minus one. |
| 139 return IntPtrAdd(reg_index, IntPtrConstant(-1)); | 126 return IntPtrAdd(reg_index, IntPtrConstant(-1)); |
| 140 } | 127 } |
| 141 | 128 |
| 142 Node* InterpreterAssembler::OperandOffset(int operand_index) { | 129 Node* InterpreterAssembler::OperandOffset(int operand_index) { |
| 143 return IntPtrConstant( | 130 return IntPtrConstant( |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 390 |
| 404 Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, | 391 Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, |
| 405 Node* value) { | 392 Node* value) { |
| 406 Node* offset = | 393 Node* offset = |
| 407 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), | 394 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), |
| 408 IntPtrConstant(Context::kHeaderSize - kHeapObjectTag)); | 395 IntPtrConstant(Context::kHeaderSize - kHeapObjectTag)); |
| 409 return Store(MachineRepresentation::kTagged, context, offset, value); | 396 return Store(MachineRepresentation::kTagged, context, offset, value); |
| 410 } | 397 } |
| 411 | 398 |
| 412 Node* InterpreterAssembler::LoadTypeFeedbackVector() { | 399 Node* InterpreterAssembler::LoadTypeFeedbackVector() { |
| 413 Node* function = Load( | 400 Node* function = LoadRegister(Register::function_closure()); |
| 414 MachineType::AnyTagged(), RegisterFileRawPointer(), | |
| 415 IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer)); | |
| 416 Node* shared_info = | 401 Node* shared_info = |
| 417 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); | 402 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); |
| 418 Node* vector = | 403 Node* vector = |
| 419 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); | 404 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); |
| 420 return vector; | 405 return vector; |
| 421 } | 406 } |
| 422 | 407 |
| 423 void InterpreterAssembler::CallPrologue() { | 408 void InterpreterAssembler::CallPrologue() { |
| 424 StoreRegister(SmiTag(BytecodeOffset()), | 409 StoreRegister(SmiTag(BytecodeOffset()), Register::bytecode_offset()); |
| 425 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); | |
| 426 | 410 |
| 427 if (FLAG_debug_code && !disable_stack_check_across_call_) { | 411 if (FLAG_debug_code && !disable_stack_check_across_call_) { |
| 428 DCHECK(stack_pointer_before_call_ == nullptr); | 412 DCHECK(stack_pointer_before_call_ == nullptr); |
| 429 stack_pointer_before_call_ = LoadStackPointer(); | 413 stack_pointer_before_call_ = LoadStackPointer(); |
| 430 } | 414 } |
| 431 made_call_ = true; | 415 made_call_ = true; |
| 432 } | 416 } |
| 433 | 417 |
| 434 void InterpreterAssembler::CallEpilogue() { | 418 void InterpreterAssembler::CallEpilogue() { |
| 435 if (FLAG_debug_code && !disable_stack_check_across_call_) { | 419 if (FLAG_debug_code && !disable_stack_check_across_call_) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); | 556 DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); |
| 573 } | 557 } |
| 574 | 558 |
| 575 void InterpreterAssembler::DispatchToBytecodeHandlerEntry( | 559 void InterpreterAssembler::DispatchToBytecodeHandlerEntry( |
| 576 Node* handler_entry, Node* bytecode_offset) { | 560 Node* handler_entry, Node* bytecode_offset) { |
| 577 if (FLAG_trace_ignition) { | 561 if (FLAG_trace_ignition) { |
| 578 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | 562 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); |
| 579 } | 563 } |
| 580 | 564 |
| 581 InterpreterDispatchDescriptor descriptor(isolate()); | 565 InterpreterDispatchDescriptor descriptor(isolate()); |
| 582 Node* args[] = {GetAccumulatorUnchecked(), RegisterFileRawPointer(), | 566 Node* args[] = {GetAccumulatorUnchecked(), bytecode_offset, |
| 583 bytecode_offset, BytecodeArrayTaggedPointer(), | 567 BytecodeArrayTaggedPointer(), DispatchTableRawPointer()}; |
| 584 DispatchTableRawPointer()}; | |
| 585 TailCallBytecodeDispatch(descriptor, handler_entry, args); | 568 TailCallBytecodeDispatch(descriptor, handler_entry, args); |
| 586 } | 569 } |
| 587 | 570 |
| 588 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { | 571 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { |
| 589 // Dispatching a wide bytecode requires treating the prefix | 572 // Dispatching a wide bytecode requires treating the prefix |
| 590 // bytecode a base pointer into the dispatch table and dispatching | 573 // bytecode a base pointer into the dispatch table and dispatching |
| 591 // the bytecode that follows relative to this base. | 574 // the bytecode that follows relative to this base. |
| 592 // | 575 // |
| 593 // Indices 0-255 correspond to bytecodes with operand_scale == 0 | 576 // Indices 0-255 correspond to bytecodes with operand_scale == 0 |
| 594 // Indices 256-511 correspond to bytecodes with operand_scale == 1 | 577 // Indices 256-511 correspond to bytecodes with operand_scale == 1 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 V8_TARGET_ARCH_S390 | 709 V8_TARGET_ARCH_S390 |
| 727 return true; | 710 return true; |
| 728 #else | 711 #else |
| 729 #error "Unknown Architecture" | 712 #error "Unknown Architecture" |
| 730 #endif | 713 #endif |
| 731 } | 714 } |
| 732 | 715 |
| 733 } // namespace interpreter | 716 } // namespace interpreter |
| 734 } // namespace internal | 717 } // namespace internal |
| 735 } // namespace v8 | 718 } // namespace v8 |
| OLD | NEW |