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 <ostream> | 7 #include <ostream> |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/frames.h" | 10 #include "src/frames.h" |
11 #include "src/interface-descriptors.h" | 11 #include "src/interface-descriptors.h" |
12 #include "src/interpreter/bytecodes.h" | 12 #include "src/interpreter/bytecodes.h" |
13 #include "src/machine-type.h" | 13 #include "src/machine-type.h" |
14 #include "src/macro-assembler.h" | 14 #include "src/macro-assembler.h" |
15 #include "src/zone.h" | 15 #include "src/zone.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 namespace interpreter { | 19 namespace interpreter { |
20 | 20 |
21 using compiler::Node; | 21 using compiler::Node; |
22 | 22 |
23 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 23 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
24 Bytecode bytecode) | 24 Bytecode bytecode) |
25 : compiler::CodeStubAssembler( | 25 : compiler::CodeStubAssembler( |
26 isolate, zone, InterpreterDispatchDescriptor(isolate), | 26 isolate, zone, InterpreterDispatchDescriptor(isolate), |
27 Code::ComputeFlags(Code::STUB), Bytecodes::ToString(bytecode), 0), | 27 Code::ComputeFlags(Code::STUB), Bytecodes::ToString(bytecode), 0), |
28 bytecode_(bytecode), | 28 bytecode_(bytecode), |
29 accumulator_( | 29 accumulator_(this, MachineRepresentation::kTagged), |
30 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)), | 30 context_(this, MachineRepresentation::kTagged), |
31 context_(Parameter(InterpreterDispatchDescriptor::kContextParameter)), | 31 dispatch_table_(this, MachineType::PointerRepresentation()), |
32 disable_stack_check_across_call_(false), | 32 disable_stack_check_across_call_(false), |
33 stack_pointer_before_call_(nullptr) { | 33 stack_pointer_before_call_(nullptr) { |
| 34 accumulator_.Bind( |
| 35 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); |
| 36 context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter)); |
| 37 dispatch_table_.Bind( |
| 38 Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter)); |
34 if (FLAG_trace_ignition) { | 39 if (FLAG_trace_ignition) { |
35 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); | 40 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); |
36 } | 41 } |
37 } | 42 } |
38 | 43 |
39 InterpreterAssembler::~InterpreterAssembler() {} | 44 InterpreterAssembler::~InterpreterAssembler() {} |
40 | 45 |
41 Node* InterpreterAssembler::GetAccumulator() { return accumulator_; } | 46 Node* InterpreterAssembler::GetAccumulator() { return accumulator_.value(); } |
42 | 47 |
43 void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } | 48 void InterpreterAssembler::SetAccumulator(Node* value) { |
| 49 accumulator_.Bind(value); |
| 50 } |
44 | 51 |
45 Node* InterpreterAssembler::GetContext() { return context_; } | 52 Node* InterpreterAssembler::GetContext() { return context_.value(); } |
46 | 53 |
47 void InterpreterAssembler::SetContext(Node* value) { | 54 void InterpreterAssembler::SetContext(Node* value) { |
48 StoreRegister(value, Register::current_context()); | 55 StoreRegister(value, Register::current_context()); |
49 context_ = value; | 56 context_.Bind(value); |
50 } | 57 } |
51 | 58 |
52 Node* InterpreterAssembler::BytecodeOffset() { | 59 Node* InterpreterAssembler::BytecodeOffset() { |
53 return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter); | 60 return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter); |
54 } | 61 } |
55 | 62 |
56 Node* InterpreterAssembler::RegisterFileRawPointer() { | 63 Node* InterpreterAssembler::RegisterFileRawPointer() { |
57 return Parameter(InterpreterDispatchDescriptor::kRegisterFileParameter); | 64 return Parameter(InterpreterDispatchDescriptor::kRegisterFileParameter); |
58 } | 65 } |
59 | 66 |
60 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 67 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { |
61 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); | 68 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); |
62 } | 69 } |
63 | 70 |
64 Node* InterpreterAssembler::DispatchTableRawPointer() { | 71 Node* InterpreterAssembler::DispatchTableRawPointer() { |
65 return Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter); | 72 return dispatch_table_.value(); |
66 } | 73 } |
67 | 74 |
68 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 75 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |
69 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 76 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |
70 } | 77 } |
71 | 78 |
72 Node* InterpreterAssembler::LoadRegister(int offset) { | 79 Node* InterpreterAssembler::LoadRegister(int offset) { |
73 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), | 80 return Load(MachineType::AnyTagged(), RegisterFileRawPointer(), |
74 Int32Constant(offset)); | 81 Int32Constant(offset)); |
75 } | 82 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 Node* shared_info = | 303 Node* shared_info = |
297 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); | 304 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); |
298 Node* vector = | 305 Node* vector = |
299 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); | 306 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); |
300 return vector; | 307 return vector; |
301 } | 308 } |
302 | 309 |
303 void InterpreterAssembler::CallPrologue() { | 310 void InterpreterAssembler::CallPrologue() { |
304 StoreRegister(SmiTag(BytecodeOffset()), | 311 StoreRegister(SmiTag(BytecodeOffset()), |
305 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); | 312 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); |
| 313 StoreRegister(DispatchTableRawPointer(), |
| 314 InterpreterFrameConstants::kDispatchTableFromRegisterPointer); |
306 | 315 |
307 if (FLAG_debug_code && !disable_stack_check_across_call_) { | 316 if (FLAG_debug_code && !disable_stack_check_across_call_) { |
308 DCHECK(stack_pointer_before_call_ == nullptr); | 317 DCHECK(stack_pointer_before_call_ == nullptr); |
309 stack_pointer_before_call_ = LoadStackPointer(); | 318 stack_pointer_before_call_ = LoadStackPointer(); |
310 } | 319 } |
311 } | 320 } |
312 | 321 |
313 void InterpreterAssembler::CallEpilogue() { | 322 void InterpreterAssembler::CallEpilogue() { |
314 if (FLAG_debug_code && !disable_stack_check_across_call_) { | 323 if (FLAG_debug_code && !disable_stack_check_across_call_) { |
315 Node* stack_pointer_after_call = LoadStackPointer(); | 324 Node* stack_pointer_after_call = LoadStackPointer(); |
316 Node* stack_pointer_before_call = stack_pointer_before_call_; | 325 Node* stack_pointer_before_call = stack_pointer_before_call_; |
317 stack_pointer_before_call_ = nullptr; | 326 stack_pointer_before_call_ = nullptr; |
318 AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, | 327 AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, |
319 kUnexpectedStackPointer); | 328 kUnexpectedStackPointer); |
320 } | 329 } |
| 330 |
| 331 // Restore dispatch table from stack frame in case the debugger has swapped us |
| 332 // to the debugger dispatch table. |
| 333 dispatch_table_.Bind(LoadRegister( |
| 334 InterpreterFrameConstants::kDispatchTableFromRegisterPointer)); |
321 } | 335 } |
322 | 336 |
323 Node* InterpreterAssembler::CallJS(Node* function, Node* context, | 337 Node* InterpreterAssembler::CallJS(Node* function, Node* context, |
324 Node* first_arg, Node* arg_count) { | 338 Node* first_arg, Node* arg_count) { |
325 Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 339 Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); |
326 Node* code_target = HeapConstant(callable.code()); | 340 Node* code_target = HeapConstant(callable.code()); |
327 return CallStub(callable.descriptor(), code_target, context, arg_count, | 341 return CallStub(callable.descriptor(), code_target, context, arg_count, |
328 first_arg, function); | 342 first_arg, function); |
329 } | 343 } |
330 | 344 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 | 492 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 |
479 return true; | 493 return true; |
480 #else | 494 #else |
481 #error "Unknown Architecture" | 495 #error "Unknown Architecture" |
482 #endif | 496 #endif |
483 } | 497 } |
484 | 498 |
485 } // namespace interpreter | 499 } // namespace interpreter |
486 } // namespace internal | 500 } // namespace internal |
487 } // namespace v8 | 501 } // namespace v8 |
OLD | NEW |