Index: runtime/vm/stub_code_x64.cc |
=================================================================== |
--- runtime/vm/stub_code_x64.cc (revision 26436) |
+++ runtime/vm/stub_code_x64.cc (working copy) |
@@ -330,7 +330,7 @@ |
// called, the stub accesses the receiver from this location directly |
// when trying to resolve the call. |
void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); |
const Immediate& raw_null = |
Immediate(reinterpret_cast<intptr_t>(Object::null())); |
@@ -338,10 +338,10 @@ |
// Push the receiver as an argument. Load the smi-tagged argument |
// count into R13 to index the receiver in the stack. There are |
- // three words (null, stub's pc marker, saved fp) above the return |
+ // four words (null, stub's pc marker, saved pp, saved fp) above the return |
// address. |
__ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
- __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize))); |
+ __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize))); |
__ pushq(RBX); // Pass IC data object. |
__ pushq(R10); // Pass arguments descriptor array. |
@@ -355,7 +355,7 @@ |
// Remove arguments. |
__ Drop(4); |
__ popq(RAX); // Get result into RAX. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
__ ret(); |
} |
@@ -380,6 +380,8 @@ |
// GC can occur only after frame is fully rewritten. |
// Stack after EnterDartFrame(0) below: |
// +------------------+ |
+// | Saved PP | <- PP |
+// +------------------+ |
// | PC marker | <- TOS |
// +------------------+ |
// | Saved FP | <- FP of stub |
@@ -391,8 +393,12 @@ |
// Parts of the code cannot GC, part of the code can GC. |
static void GenerateDeoptimizationSequence(Assembler* assembler, |
bool preserve_result) { |
- // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
- __ EnterDartFrame(0); |
+ // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
+ // is no need to set the correct PC marker or load PP, since they get patched. |
+ __ EnterFrame(0); |
+ __ pushq(Immediate(0)); |
+ __ pushq(PP); |
+ |
// The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry |
// and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. |
const intptr_t saved_result_slot_from_fp = |
@@ -422,14 +428,18 @@ |
__ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); |
} |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
__ popq(RCX); // Preserve return address. |
__ movq(RSP, RBP); // Discard optimized frame. |
__ subq(RSP, RAX); // Reserve space for deoptimized frame. |
__ pushq(RCX); // Restore return address. |
- // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. |
- __ EnterDartFrame(0); |
+ // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
+ // is no need to set the correct PC marker or load PP, since they get patched. |
+ __ EnterFrame(0); |
+ __ pushq(Immediate(0)); |
+ __ pushq(PP); |
+ |
if (preserve_result) { |
__ pushq(RBX); // Preserve result as first local. |
} |
@@ -441,7 +451,7 @@ |
__ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
} |
// Code above cannot cause GC. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
// 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 |
@@ -486,13 +496,14 @@ |
void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); |
// Load the receiver into RAX. The argument count in the arguments |
// descriptor in R10 is a smi. |
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
- // Two words (saved fp, stub's pc marker) in the stack above the return |
- // address. |
- __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); |
+ // Three words (saved pp, saved fp, stub's pc marker) |
+ // in the stack above the return address. |
+ __ movq(RAX, Address(RSP, RAX, TIMES_4, |
+ kSavedAboveReturnAddress * kWordSize)); |
// Preserve IC data and arguments descriptor. |
__ pushq(RBX); |
__ pushq(R10); |
@@ -511,7 +522,7 @@ |
__ popq(RAX); // Return value from the runtime call (instructions). |
__ popq(R10); // Restore arguments descriptor. |
__ popq(RBX); // Restore IC data. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
Label lookup; |
__ cmpq(RAX, raw_null); |
@@ -761,12 +772,12 @@ |
// RCX : new context containing the current isolate pointer. |
void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
// Save frame pointer coming in. |
- __ EnterFrame(0); |
+ __ EnterStubFrame(); |
// Save arguments descriptor array and new context. |
- const intptr_t kArgumentsDescOffset = -1 * kWordSize; |
+ const intptr_t kArgumentsDescOffset = -2 * kWordSize; |
__ pushq(RSI); |
- const intptr_t kNewContextOffset = -2 * kWordSize; |
+ const intptr_t kNewContextOffset = -3 * kWordSize; |
__ pushq(RCX); |
// Save C++ ABI callee-saved registers. |
@@ -792,7 +803,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 == -8); |
+ ASSERT(kExitLinkSlotFromEntryFp == -9); |
__ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); |
__ pushq(RAX); |
__ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
@@ -804,7 +815,7 @@ |
// EntryFrame::SavedContext reads the context saved in this frame. |
// The constant kSavedContextSlotFromEntryFp must be kept in sync with |
// the code below. |
- ASSERT(kSavedContextSlotFromEntryFp == -9); |
+ ASSERT(kSavedContextSlotFromEntryFp == -10); |
__ movq(RAX, Address(R8, Isolate::top_context_offset())); |
__ pushq(RAX); |
@@ -1217,7 +1228,7 @@ |
__ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); |
} |
// Create a stub frame. |
- __ EnterStubFrame(); |
+ __ EnterStubFrame(true); |
__ pushq(raw_null); // Setup space on stack for return value. |
__ PushObject(cls); // Push class of object to be allocated. |
if (is_cls_parameterized) { |
@@ -1234,7 +1245,7 @@ |
__ popq(RAX); // Pop result (newly allocated object). |
// RAX: new object |
// Restore the frame pointer. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
__ ret(); |
} |
@@ -1254,8 +1265,10 @@ |
func.IsImplicitInstanceClosureFunction(); |
const Class& cls = Class::ZoneHandle(func.signature_class()); |
const bool has_type_arguments = cls.HasTypeArguments(); |
- const intptr_t kTypeArgumentsOffset = 1 * kWordSize; |
- const intptr_t kReceiverOffset = 2 * kWordSize; |
+ |
+ __ EnterStubFrame(true); // Uses pool pointer to refer to function. |
+ const intptr_t kTypeArgumentsOffset = 4 * kWordSize; |
+ const intptr_t kReceiverOffset = 5 * kWordSize; |
const intptr_t closure_size = Closure::InstanceSize(); |
const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
if (FLAG_inline_alloc && |
@@ -1340,6 +1353,7 @@ |
// Done allocating and initializing the instance. |
// RAX: new object. |
__ addq(RAX, Immediate(kHeapObjectTag)); |
+ __ LeaveFrame(true); |
__ ret(); |
__ Bind(&slow_case); |
@@ -1350,8 +1364,7 @@ |
if (is_implicit_instance_closure) { |
__ movq(RAX, Address(RSP, kReceiverOffset)); |
} |
- // Create the stub frame. |
- __ EnterStubFrame(); |
+ |
__ pushq(raw_null); // Setup space on stack for the return value. |
__ PushObject(func); |
if (is_implicit_instance_closure) { |
@@ -1375,7 +1388,7 @@ |
__ popq(RAX); // Pop the result. |
// RAX: New closure object. |
// Restore the calling frame. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
__ ret(); |
} |
@@ -1827,7 +1840,7 @@ |
__ LeaveFrame(); |
__ popq(R11); // discard return address of call to this stub. |
- __ LeaveFrame(); |
+ __ LeaveFrame(true); |
__ ret(); |
} |
@@ -2081,7 +2094,7 @@ |
__ Bind(&update_ic_data); |
- // RCX: ICData |
+ // RBX: ICData |
__ movq(RAX, Address(RSP, 1 * kWordSize)); |
__ movq(R13, Address(RSP, 2 * kWordSize)); |
__ EnterStubFrame(); |