Chromium Code Reviews| 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; |