Index: runtime/vm/stub_code_x64.cc |
=================================================================== |
--- runtime/vm/stub_code_x64.cc (revision 29988) |
+++ runtime/vm/stub_code_x64.cc (working copy) |
@@ -252,7 +252,7 @@ |
// Input parameters: |
// R10: arguments descriptor array. |
void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
__ pushq(R10); // Preserve arguments descriptor array. |
// Setup space on stack for return value. |
__ PushObject(Object::null_object(), PP); |
@@ -260,7 +260,7 @@ |
__ popq(RAX); // Get Code object result. |
__ popq(R10); // Restore arguments descriptor array. |
// Remove the stub frame as we are about to jump to the dart function. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
__ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
@@ -272,7 +272,7 @@ |
// (invalid because its function was optimized or deoptimized). |
// R10: arguments descriptor array. |
void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
__ pushq(R10); // Preserve arguments descriptor array. |
// Setup space on stack for return value. |
__ PushObject(Object::null_object(), PP); |
@@ -281,7 +281,7 @@ |
__ popq(R10); // Restore arguments descriptor array. |
__ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
__ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ jmp(RAX); |
__ int3(); |
} |
@@ -323,7 +323,7 @@ |
// called, the stub accesses the receiver from this location directly |
// when trying to resolve the call. |
void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
- __ EnterStubFrameWithPP(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
__ PushObject(Object::null_object(), PP); // Space for the return value. |
// Push the receiver as an argument. Load the smi-tagged argument |
@@ -345,7 +345,7 @@ |
// Remove arguments. |
__ Drop(4); |
__ popq(RAX); // Get result into RAX. |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -418,9 +418,8 @@ |
__ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); |
} |
- // There is a Dart Frame on the stack. We just need the PP. |
- __ movq(PP, Address(RBP, -2 * kWordSize)); |
- __ LeaveFrame(); |
+ // There is a Dart Frame on the stack. We must restore PP and leave frame. |
+ __ LeaveDartFrame(); |
__ popq(RCX); // Preserve return address. |
__ movq(RSP, RBP); // Discard optimized frame. |
@@ -444,9 +443,8 @@ |
__ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
} |
// Code above cannot cause GC. |
- // There is a Dart Frame on the stack. We just need the PP. |
- __ movq(PP, Address(RBP, -2 * kWordSize)); |
- __ LeaveFrame(); |
+ // There is a Dart Frame on the stack. We must restore PP and leave frame. |
+ __ LeaveDartFrame(); |
// Frame is fully rewritten at this point and it is safe to perform a GC. |
// Materialize any objects that were deferred by FillFrame because they |
@@ -464,7 +462,7 @@ |
if (preserve_result) { |
__ popq(RAX); // Restore result. |
} |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ popq(RCX); // Pop return address. |
__ addq(RSP, RBX); // Remove materialization arguments. |
@@ -491,7 +489,7 @@ |
void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
- __ EnterStubFrameWithPP(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
// Load the receiver into RAX. The argument count in the arguments |
// descriptor in R10 is a smi. |
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
@@ -516,7 +514,7 @@ |
__ popq(RAX); // Return value from the runtime call (instructions). |
__ popq(R10); // Restore arguments descriptor. |
__ popq(RBX); // Restore IC data. |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
Label lookup; |
__ CompareObject(RAX, Object::null_object(), PP); |
@@ -648,7 +646,7 @@ |
__ Bind(&slow_case); |
// Create a stub frame as we are pushing some objects on the stack before |
// calling into the runtime. |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
Ivan Posva
2013/11/07 22:11:58
Where PP is only used to access null we do not nee
siva
2013/11/07 23:08:19
Done.
|
// Setup space on stack for return value. |
__ PushObject(Object::null_object(), PP); |
__ pushq(R10); // Array length as Smi. |
@@ -657,7 +655,7 @@ |
__ popq(RAX); // Pop element type argument. |
__ popq(R10); // Pop array length argument. |
__ popq(RAX); // Pop return value from return slot. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -715,7 +713,7 @@ |
__ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
// Remove the stub frame as we are about to jump to the closure function. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ Bind(&function_compiled); |
// RAX: Code. |
@@ -751,7 +749,7 @@ |
__ popq(RAX); // Get result into RAX. |
// Remove the stub frame as we are about to return. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -765,16 +763,13 @@ |
// RCX : new context containing the current isolate pointer. |
void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
// Save frame pointer coming in. |
- __ EnterStubFrameWithPP(); |
+ __ EnterFrame(0); |
// At this point, the stack looks like: |
- // | saved RC15/PP | <-- RSP / TOS |
- // | "saved PC area" = 0 | |
// | saved RBP | <-- RBP |
// | saved PC (return to DartEntry::InvokeFunction) | |
- // The old frame pointer, the return address, the old R15 (for PP). |
- const intptr_t kInitialOffset = 3; |
+ const intptr_t kInitialOffset = 1; |
// Save arguments descriptor array and new context. |
const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; |
__ pushq(RSI); |
@@ -786,8 +781,13 @@ |
__ pushq(R12); |
__ pushq(R13); |
__ pushq(R14); |
- // R15 is already saved above by EnterStubFrameWithPP. |
+ __ pushq(R15); |
+ // We now load the pool pointer(PP) as we are about to invoke dart code and we |
+ // could potentially invoke some intrinsic functions which need the PP to be |
+ // set up. |
+ __ LoadPoolPointer(PP); |
+ |
// If any additional (or fewer) values are pushed, the offsets in |
// kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be |
// changed. |
@@ -808,7 +808,7 @@ |
// StackFrameIterator reads the top exit frame info saved in this frame. |
// The constant kExitLinkSlotFromEntryFp must be kept in sync with the |
// code below. |
- ASSERT(kExitLinkSlotFromEntryFp == -9); |
+ ASSERT(kExitLinkSlotFromEntryFp == -8); |
__ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); |
__ pushq(RAX); |
__ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
@@ -820,7 +820,7 @@ |
// EntryFrame::SavedContext reads the context saved in this frame. |
// The constant kSavedContextSlotFromEntryFp must be kept in sync with |
// the code below. |
- ASSERT(kSavedContextSlotFromEntryFp == -10); |
+ ASSERT(kSavedContextSlotFromEntryFp == -9); |
__ movq(RAX, Address(R8, Isolate::top_context_offset())); |
__ pushq(RAX); |
@@ -878,14 +878,14 @@ |
__ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX); |
// Restore C++ ABI callee-saved registers. |
- // R15 will be restored below by LeaveFrameWithPP. |
+ __ popq(R15); |
__ popq(R14); |
__ popq(R13); |
__ popq(R12); |
__ popq(RBX); |
// Restore the frame pointer. |
- __ LeaveFrameWithPP(); |
+ __ LeaveFrame(); |
__ ret(); |
} |
@@ -1009,7 +1009,7 @@ |
__ popq(RAX); // Pop the new context object. |
// RAX: new object |
// Restore the frame pointer. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -1226,7 +1226,7 @@ |
__ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); |
} |
// Create a stub frame. |
- __ EnterStubFrameWithPP(); |
+ __ EnterStubFrame(true); // Uses PP to access class object. |
__ pushq(R12); // Setup space on stack for return value. |
__ PushObject(cls, PP); // Push class of object to be allocated. |
if (is_cls_parameterized) { |
@@ -1243,7 +1243,7 @@ |
__ popq(RAX); // Pop result (newly allocated object). |
// RAX: new object |
// Restore the frame pointer. |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -1262,7 +1262,7 @@ |
const Class& cls = Class::ZoneHandle(func.signature_class()); |
const bool has_type_arguments = cls.NumTypeArguments() > 0; |
- __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function. |
+ __ EnterStubFrame(true); // Uses pool pointer to refer to function. |
__ LoadObject(R12, Object::null_object(), PP); |
const intptr_t kTypeArgumentsOffset = 4 * kWordSize; |
const intptr_t kReceiverOffset = 5 * kWordSize; |
@@ -1351,7 +1351,7 @@ |
// Done allocating and initializing the instance. |
// RAX: new object. |
__ addq(RAX, Immediate(kHeapObjectTag)); |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
__ ret(); |
__ Bind(&slow_case); |
@@ -1386,7 +1386,7 @@ |
__ popq(RAX); // Pop the result. |
// RAX: New closure object. |
// Restore the calling frame. |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -1400,7 +1400,7 @@ |
// RBX : ic-data. |
// R10 : arguments descriptor array. |
void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
// Load the receiver. |
__ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
@@ -1422,7 +1422,7 @@ |
__ popq(RAX); // Get result into RAX. |
// Remove the stub frame as we are about to return. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -1443,7 +1443,7 @@ |
__ popq(RAX); // Discard argument; |
__ popq(ic_reg); // Restore. |
__ popq(func_reg); // Restore. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
} |
__ incq(FieldAddress(func_reg, Function::usage_counter_offset())); |
} |
@@ -1497,7 +1497,7 @@ |
__ pushq(RBX); |
__ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
__ popq(RBX); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ Bind(¬_stepping); |
// Load arguments descriptor into R10. |
@@ -1578,7 +1578,7 @@ |
__ popq(RAX); // Pop returned code object into RAX (null if not found). |
__ popq(RBX); // Restore IC data array. |
__ popq(R10); // Restore arguments descriptor array. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
Label call_target_function; |
__ cmpq(RAX, R12); |
__ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); |
@@ -1614,7 +1614,7 @@ |
__ popq(RAX); // Restore function. |
__ popq(RBX); // Restore IC data array. |
__ popq(R10); // Restore arguments descriptor array. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
__ Bind(&is_compiled); |
} |
@@ -1744,7 +1744,7 @@ |
__ pushq(RBX); // Preserve IC data object. |
__ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
__ popq(RBX); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ Bind(¬_stepping); |
// RBX: IC data object (preserved). |
@@ -1779,7 +1779,7 @@ |
__ popq(RAX); // Discard argument. |
__ popq(RBX); // Restore IC data object. |
__ popq(R13); // Restore target function. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ movq(RAX, FieldAddress(R13, Function::code_offset())); |
__ Bind(&target_is_compiled); |
@@ -1812,7 +1812,7 @@ |
__ popq(RAX); // Restore function. |
__ popq(RCX); // Restore IC data array. |
__ popq(RDX); // Restore arguments descriptor array. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ ret(); |
} |
@@ -1820,7 +1820,7 @@ |
// RBX, R10: May contain arguments to runtime stub. |
// TOS(0): return address (Dart code). |
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
// Preserve runtime args. |
__ pushq(RBX); |
__ pushq(R10); |
@@ -1832,7 +1832,7 @@ |
__ popq(RAX); // Address of original. |
__ popq(R10); // Restore arguments. |
__ popq(RBX); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ jmp(RAX); // Jump to original stub. |
} |
@@ -1840,14 +1840,14 @@ |
// RBX: ICData (unoptimized static call) |
// TOS(0): return address (Dart code). |
void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
__ LoadObject(R12, Object::null_object(), PP); |
__ pushq(RBX); // Preserve IC data for unoptimized call. |
__ pushq(R12); // Room for result. |
__ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
__ popq(RAX); // Code object. |
__ popq(RBX); // Restore IC data. |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
// Load arguments descriptor into R10. |
__ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
@@ -1865,10 +1865,10 @@ |
__ pushq(RAX); |
__ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
__ popq(RAX); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ popq(R11); // discard return address of call to this stub. |
- __ LeaveFrameWithPP(); |
+ __ LeaveDartFrame(); |
__ ret(); |
} |
@@ -1880,7 +1880,7 @@ |
__ pushq(RBX); |
__ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
__ popq(RBX); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
// Find out which dispatch stub to call. |
Label test_two, test_three, test_four; |
@@ -2042,7 +2042,7 @@ |
// RDI: function to be reoptimized. |
// R10: argument descriptor (preserved). |
void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
- __ EnterStubFrameWithPP(); |
+ __ EnterStubFrame(true); // Uses PP to access null object. |
__ LoadObject(R12, Object::null_object(), PP); |
__ pushq(R10); |
__ pushq(R12); // Setup space on stack for return value. |
@@ -2053,7 +2053,7 @@ |
__ popq(R10); // Restore argument descriptor. |
__ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
__ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
- __ LeaveFrameWithPP(); |
+ __ LeaveStubFrame(); |
__ jmp(RAX); |
__ int3(); |
} |
@@ -2139,7 +2139,7 @@ |
__ j(EQUAL, ¬_stepping, Assembler::kNearJump); |
__ EnterStubFrame(); |
__ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
- __ LeaveFrame(); |
+ __ LeaveStubFrame(); |
__ Bind(¬_stepping); |
const Register left = RAX; |