Index: src/x64/builtins-x64.cc |
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc |
index 55961c7ff059cc7ab9ddf31dd77599c0e587d70c..9e0221b9bcc36503ed08fddc72c04d11b6ab9425 100644 |
--- a/src/x64/builtins-x64.cc |
+++ b/src/x64/builtins-x64.cc |
@@ -696,20 +696,23 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
// Get the bytecode array from the function object and load the pointer to the |
// first entry into edi (InterpreterBytecodeRegister). |
- __ movp(r14, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
- __ movp(r14, FieldOperand(r14, SharedFunctionInfo::kFunctionDataOffset)); |
+ __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
+ __ movp(kInterpreterBytecodeArrayRegister, |
+ FieldOperand(rax, SharedFunctionInfo::kFunctionDataOffset)); |
if (FLAG_debug_code) { |
// Check function data field is actually a BytecodeArray object. |
- __ AssertNotSmi(r14); |
- __ CmpObjectType(r14, BYTECODE_ARRAY_TYPE, rax); |
+ __ AssertNotSmi(kInterpreterBytecodeArrayRegister); |
+ __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, |
+ rax); |
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
} |
// Allocate the local and temporary register file on the stack. |
{ |
// Load frame size from the BytecodeArray object. |
- __ movl(rcx, FieldOperand(r14, BytecodeArray::kFrameSizeOffset)); |
+ __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, |
+ BytecodeArray::kFrameSizeOffset)); |
// Do a stack check to ensure we don't go over the limit. |
Label ok; |
@@ -721,16 +724,17 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
__ bind(&ok); |
// If ok, push undefined as the initial value for all register file entries. |
- // Note: there should always be at least one stack slot for the return |
- // register in the register file. |
Label loop_header; |
+ Label loop_check; |
__ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
+ __ j(always, &loop_check); |
__ bind(&loop_header); |
// TODO(rmcilroy): Consider doing more than one push per loop iteration. |
__ Push(rdx); |
// Continue loop if not done. |
+ __ bind(&loop_check); |
__ subp(rcx, Immediate(kPointerSize)); |
- __ j(not_equal, &loop_header, Label::kNear); |
+ __ j(greater_equal, &loop_header, Label::kNear); |
} |
// TODO(rmcilroy): List of things not currently dealt with here but done in |
@@ -763,18 +767,29 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
__ bind(&ok); |
} |
- // Load bytecode offset and dispatch table into registers. |
- __ movp(r12, Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
- __ LoadRoot(r15, Heap::kInterpreterTableRootIndex); |
- __ addp(r15, Immediate(FixedArray::kHeaderSize - kHeapObjectTag)); |
+ // Load accumulator, register file, bytecode offset, dispatch table into |
+ // registers. |
+ __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); |
+ __ movp(kInterpreterRegisterFileRegister, rbp); |
+ __ subp( |
+ kInterpreterRegisterFileRegister, |
+ Immediate(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp)); |
+ __ movp(kInterpreterBytecodeOffsetRegister, |
+ Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
+ __ LoadRoot(kInterpreterDispatchTableRegister, |
+ Heap::kInterpreterTableRootIndex); |
+ __ addp(kInterpreterDispatchTableRegister, |
+ Immediate(FixedArray::kHeaderSize - kHeapObjectTag)); |
// Dispatch to the first bytecode handler for the function. |
- __ movzxbp(rax, Operand(r14, r12, times_1, 0)); |
- __ movp(rax, Operand(r15, rax, times_pointer_size, 0)); |
+ __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
+ kInterpreterBytecodeOffsetRegister, times_1, 0)); |
+ __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
+ times_pointer_size, 0)); |
// TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging |
// and header removal. |
- __ addp(rax, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
- __ jmp(rax); |
+ __ addp(rbx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
+ __ call(rbx); |
} |
@@ -785,9 +800,8 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
// - Support profiler (specifically decrementing profiling_counter |
// appropriately and calling out to HandleInterrupts if necessary). |
- // Load return value into r0. |
- __ movp(rax, Operand(rbp, -kPointerSize - |
- StandardFrameConstants::kFixedFrameSizeFromFp)); |
+ // The return value is in accumulator, which is already in rax. |
+ |
// Leave the frame (also dropping the register file). |
__ leave(); |
// Return droping receiver + arguments. |