| Index: runtime/vm/stub_code_x64.cc
|
| ===================================================================
|
| --- runtime/vm/stub_code_x64.cc (revision 27291)
|
| +++ runtime/vm/stub_code_x64.cc (working copy)
|
| @@ -83,9 +83,8 @@
|
| __ movq(RBX, Address(CTX, Isolate::top_context_offset()));
|
|
|
| // Reset Context pointer in Isolate structure.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ movq(Address(CTX, Isolate::top_context_offset()), R12);
|
|
|
| // Cache Context pointer into CTX while executing Dart code.
|
| __ movq(CTX, RBX);
|
| @@ -172,9 +171,8 @@
|
| __ movq(R8, Address(CTX, Isolate::top_context_offset()));
|
|
|
| // Reset Context pointer in Isolate structure.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ movq(Address(CTX, Isolate::top_context_offset()), R12);
|
|
|
| // Cache Context pointer into CTX while executing Dart code.
|
| __ movq(CTX, R8);
|
| @@ -240,9 +238,8 @@
|
| __ movq(R8, Address(CTX, Isolate::top_context_offset()));
|
|
|
| // Reset Context pointer in Isolate structure.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ movq(Address(CTX, Isolate::top_context_offset()), raw_null);
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ movq(Address(CTX, Isolate::top_context_offset()), R12);
|
|
|
| // Cache Context pointer into CTX while executing Dart code.
|
| __ movq(CTX, R8);
|
| @@ -255,11 +252,10 @@
|
| // Input parameters:
|
| // R10: arguments descriptor array.
|
| void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| __ EnterStubFrame();
|
| __ pushq(R10); // Preserve arguments descriptor array.
|
| - __ pushq(raw_null); // Setup space on stack for return value.
|
| + // Setup space on stack for return value.
|
| + __ PushObject(Object::Handle());
|
| __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
|
| __ popq(RAX); // Get Code object result.
|
| __ popq(R10); // Restore arguments descriptor array.
|
| @@ -276,11 +272,10 @@
|
| // (invalid because its function was optimized or deoptimized).
|
| // R10: arguments descriptor array.
|
| void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| __ EnterStubFrame();
|
| __ pushq(R10); // Preserve arguments descriptor array.
|
| - __ pushq(raw_null); // Setup space on stack for return value.
|
| + // Setup space on stack for return value.
|
| + __ PushObject(Object::Handle());
|
| __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
|
| __ popq(RAX); // Get Code object.
|
| __ popq(R10); // Restore arguments descriptor array.
|
| @@ -296,11 +291,9 @@
|
| // R10: smi-tagged argument count, may be zero.
|
| // RBP[kParamEndSlotFromFp + 1]: last argument.
|
| static void PushArgumentsArray(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| -
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| // Allocate array to store arguments of caller.
|
| - __ movq(RBX, raw_null); // Null element type for raw Array.
|
| + __ movq(RBX, R12); // Null element type for raw Array.
|
| __ call(&StubCode::AllocateArrayLabel());
|
| __ SmiUntag(R10);
|
| // RAX: newly allocated array.
|
| @@ -330,18 +323,15 @@
|
| // called, the stub accesses the receiver from this location directly
|
| // when trying to resolve the call.
|
| void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
|
| - __ EnterStubFrame();
|
| + __ EnterStubFrameWithPP();
|
| + __ PushObject(Object::Handle()); // Space for the return value.
|
|
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ pushq(raw_null); // Space for the return value.
|
| -
|
| // 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 +345,7 @@
|
| // Remove arguments.
|
| __ Drop(4);
|
| __ popq(RAX); // Get result into RAX.
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
| __ ret();
|
| }
|
|
|
| @@ -378,8 +368,10 @@
|
| // - Fill the unoptimized frame.
|
| // - Materialize objects that require allocation (e.g. Double instances).
|
| // GC can occur only after frame is fully rewritten.
|
| -// Stack after EnterDartFrame(0) below:
|
| +// Stack after EnterDartFrame(0, PP, kNoRegister) below:
|
| // +------------------+
|
| +// | Saved PP | <- PP
|
| +// +------------------+
|
| // | PC marker | <- TOS
|
| // +------------------+
|
| // | Saved FP | <- FP of stub
|
| @@ -391,8 +383,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 +418,21 @@
|
| __ 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();
|
| +
|
| __ 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,6 +444,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();
|
|
|
| // Frame is fully rewritten at this point and it is safe to perform a GC.
|
| @@ -486,20 +491,20 @@
|
|
|
|
|
| void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
|
| - __ EnterStubFrame();
|
| + __ EnterStubFrameWithPP();
|
| // 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);
|
|
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
|
| - __ pushq(raw_null); // Space for the result of the runtime call.
|
| + // Space for the result of the runtime call.
|
| + __ PushObject(Object::Handle());
|
| __ pushq(RAX); // Receiver.
|
| __ pushq(RBX); // IC data.
|
| __ pushq(R10); // Arguments descriptor.
|
| @@ -511,10 +516,10 @@
|
| __ popq(RAX); // Return value from the runtime call (instructions).
|
| __ popq(R10); // Restore arguments descriptor.
|
| __ popq(RBX); // Restore IC data.
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
|
|
| Label lookup;
|
| - __ cmpq(RAX, raw_null);
|
| + __ CompareObject(RAX, Object::Handle());
|
| __ j(EQUAL, &lookup, Assembler::kNearJump);
|
| __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
|
| __ jmp(RAX);
|
| @@ -532,8 +537,6 @@
|
| // The newly allocated object is returned in RAX.
|
| void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
|
| Label slow_case;
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
|
|
| if (FLAG_inline_alloc) {
|
| // Compute the size to be allocated, it is based on the array length
|
| @@ -622,13 +625,14 @@
|
| __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
|
| // RBX: iterator which initially points to the start of the variable
|
| // data area to be initialized.
|
| + __ LoadObject(R13, Object::Handle(), PP);
|
| Label done;
|
| Label init_loop;
|
| __ Bind(&init_loop);
|
| __ cmpq(RBX, R12);
|
| __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
|
| // TODO(cshapiro): StoreIntoObjectNoBarrier
|
| - __ movq(Address(RBX, 0), raw_null);
|
| + __ movq(Address(RBX, 0), R13);
|
| __ addq(RBX, Immediate(kWordSize));
|
| __ jmp(&init_loop, Assembler::kNearJump);
|
| __ Bind(&done);
|
| @@ -645,7 +649,8 @@
|
| // Create a stub frame as we are pushing some objects on the stack before
|
| // calling into the runtime.
|
| __ EnterStubFrame();
|
| - __ pushq(raw_null); // Setup space on stack for return value.
|
| + // Setup space on stack for return value.
|
| + __ PushObject(Object::Handle());
|
| __ pushq(R10); // Array length as Smi.
|
| __ pushq(RBX); // Element type.
|
| __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
|
| @@ -663,17 +668,16 @@
|
| // called, the stub accesses the closure from this location directly
|
| // when trying to resolve the call.
|
| void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| -
|
| // Load num_args.
|
| __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
|
| // Load closure object in R13.
|
| __ movq(R13, Address(RSP, RAX, TIMES_4, 0)); // RAX is a Smi.
|
|
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| +
|
| // Verify that R13 is a closure by checking its class.
|
| Label not_closure;
|
| - __ cmpq(R13, raw_null);
|
| + __ cmpq(R13, R12);
|
| // Not a closure, but null object.
|
| __ j(EQUAL, ¬_closure);
|
| __ testq(R13, Immediate(kSmiTagMask));
|
| @@ -682,7 +686,7 @@
|
| // class.signature_function() is not null.
|
| __ LoadClass(RAX, R13);
|
| __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset()));
|
| - __ cmpq(RAX, raw_null);
|
| + __ cmpq(RAX, R12);
|
| // Actual class is not a closure class.
|
| __ j(EQUAL, ¬_closure, Assembler::kNearJump);
|
|
|
| @@ -694,7 +698,7 @@
|
|
|
| // Load closure function code in RAX.
|
| __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
|
| - __ cmpq(RAX, raw_null);
|
| + __ cmpq(RAX, R12);
|
| Label function_compiled;
|
| __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
|
|
|
| @@ -733,8 +737,8 @@
|
| // Create a stub frame as we are pushing some objects on the stack before
|
| // calling into the runtime.
|
| __ EnterStubFrame();
|
| -
|
| - __ pushq(raw_null); // Setup space on stack for result from call.
|
| + // Setup space on stack for result from call.
|
| + __ pushq(R12);
|
| __ pushq(R10); // Arguments descriptor.
|
| // Load smi-tagged arguments array length, including the non-closure.
|
| __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
|
| @@ -761,12 +765,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 +796,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 +808,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);
|
|
|
| @@ -881,8 +885,7 @@
|
| // Output:
|
| // RAX: new allocated RawContext object.
|
| void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| if (FLAG_inline_alloc) {
|
| const Class& context_class = Class::ZoneHandle(Object::context_class());
|
| Label slow_case;
|
| @@ -957,12 +960,10 @@
|
| // R13: Isolate, not an object.
|
| __ movq(FieldAddress(RAX, Context::isolate_offset()), R13);
|
|
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| // Setup the parent field.
|
| // RAX: new object.
|
| // R10: number of context variables.
|
| - __ movq(FieldAddress(RAX, Context::parent_offset()), raw_null);
|
| + __ movq(FieldAddress(RAX, Context::parent_offset()), R12);
|
|
|
| // Initialize the context variables.
|
| // RAX: new object.
|
| @@ -974,7 +975,7 @@
|
| __ jmp(&entry, Assembler::kNearJump);
|
| __ Bind(&loop);
|
| __ decq(R10);
|
| - __ movq(Address(R13, R10, TIMES_8, 0), raw_null);
|
| + __ movq(Address(R13, R10, TIMES_8, 0), R12);
|
| __ Bind(&entry);
|
| __ cmpq(R10, Immediate(0));
|
| __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
|
| @@ -988,7 +989,7 @@
|
| }
|
| // Create a stub frame.
|
| __ EnterStubFrame();
|
| - __ pushq(raw_null); // Setup space on stack for the return value.
|
| + __ pushq(R12); // Setup space on stack for the return value.
|
| __ SmiTag(R10);
|
| __ pushq(R10); // Push number of context variables.
|
| __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
|
| @@ -1072,8 +1073,6 @@
|
| const Class& cls) {
|
| const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
|
| const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| // The generated code is different if the class is parameterized.
|
| const bool is_cls_parameterized = cls.HasTypeArguments();
|
| ASSERT(!cls.HasTypeArguments() ||
|
| @@ -1085,6 +1084,7 @@
|
| const intptr_t instance_size = cls.instance_size();
|
| ASSERT(instance_size > 0);
|
| const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize();
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| if (FLAG_inline_alloc &&
|
| Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) {
|
| Label slow_case;
|
| @@ -1168,9 +1168,6 @@
|
| __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags));
|
|
|
| // Initialize the remaining words of the object.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| -
|
| // RAX: new object start.
|
| // RBX: next object start.
|
| // RDI: new object type arguments (if is_cls_parameterized).
|
| @@ -1181,7 +1178,7 @@
|
| for (intptr_t current_offset = sizeof(RawObject);
|
| current_offset < instance_size;
|
| current_offset += kWordSize) {
|
| - __ movq(Address(RAX, current_offset), raw_null);
|
| + __ movq(Address(RAX, current_offset), R12);
|
| }
|
| } else {
|
| __ leaq(RCX, Address(RAX, sizeof(RawObject)));
|
| @@ -1195,7 +1192,7 @@
|
| __ Bind(&init_loop);
|
| __ cmpq(RCX, RBX);
|
| __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
|
| - __ movq(Address(RCX, 0), raw_null);
|
| + __ movq(Address(RCX, 0), R12);
|
| __ addq(RCX, Immediate(kWordSize));
|
| __ jmp(&init_loop, Assembler::kNearJump);
|
| __ Bind(&done);
|
| @@ -1217,14 +1214,14 @@
|
| __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
|
| }
|
| // Create a stub frame.
|
| - __ EnterStubFrame();
|
| - __ pushq(raw_null); // Setup space on stack for return value.
|
| + __ EnterStubFrameWithPP();
|
| + __ pushq(R12); // Setup space on stack for return value.
|
| __ PushObject(cls); // Push class of object to be allocated.
|
| if (is_cls_parameterized) {
|
| __ pushq(RAX); // Push type arguments of object to be allocated.
|
| __ pushq(RDX); // Push type arguments of instantiator.
|
| } else {
|
| - __ pushq(raw_null); // Push null type arguments.
|
| + __ pushq(R12); // Push null type arguments.
|
| __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
|
| }
|
| __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object.
|
| @@ -1234,7 +1231,7 @@
|
| __ popq(RAX); // Pop result (newly allocated object).
|
| // RAX: new object
|
| // Restore the frame pointer.
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
| __ ret();
|
| }
|
|
|
| @@ -1246,16 +1243,17 @@
|
| // RSP : points to return address.
|
| void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
|
| const Function& func) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| ASSERT(func.IsClosureFunction());
|
| ASSERT(!func.IsImplicitStaticClosureFunction());
|
| const bool is_implicit_instance_closure =
|
| 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;
|
| +
|
| + __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function.
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + 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 &&
|
| @@ -1298,7 +1296,8 @@
|
| // RAX: new closure object.
|
| // RBX: new context object (only if is_implicit_closure).
|
| // R13: next object start.
|
| - __ LoadObject(R10, func); // Load function of closure to be allocated.
|
| + // Load function of closure to be allocated.
|
| + __ LoadObject(R10, func, PP);
|
| __ movq(Address(RAX, Closure::function_offset()), R10);
|
|
|
| // Setup the context for this closure.
|
| @@ -1320,7 +1319,7 @@
|
| __ movq(Address(RBX, Context::isolate_offset()), R10);
|
|
|
| // Set the parent to null.
|
| - __ movq(Address(RBX, Context::parent_offset()), raw_null);
|
| + __ movq(Address(RBX, Context::parent_offset()), R12);
|
|
|
| // Initialize the context variable to the receiver.
|
| __ movq(R10, Address(RSP, kReceiverOffset));
|
| @@ -1340,6 +1339,7 @@
|
| // Done allocating and initializing the instance.
|
| // RAX: new object.
|
| __ addq(RAX, Immediate(kHeapObjectTag));
|
| + __ LeaveFrameWithPP();
|
| __ ret();
|
|
|
| __ Bind(&slow_case);
|
| @@ -1350,9 +1350,8 @@
|
| 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.
|
| +
|
| + __ pushq(R12); // Setup space on stack for the return value.
|
| __ PushObject(func);
|
| if (is_implicit_instance_closure) {
|
| __ pushq(RAX); // Receiver.
|
| @@ -1360,7 +1359,7 @@
|
| if (has_type_arguments) {
|
| __ pushq(RCX); // Push type arguments of closure to be allocated.
|
| } else {
|
| - __ pushq(raw_null); // Push null type arguments.
|
| + __ pushq(R12); // Push null type arguments.
|
| }
|
| if (is_implicit_instance_closure) {
|
| __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3);
|
| @@ -1375,7 +1374,7 @@
|
| __ popq(RAX); // Pop the result.
|
| // RAX: New closure object.
|
| // Restore the calling frame.
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
| __ ret();
|
| }
|
|
|
| @@ -1395,9 +1394,8 @@
|
| __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
|
| __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize));
|
|
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ pushq(R12); // Setup space on stack for result from noSuchMethod.
|
| __ pushq(RAX); // Receiver.
|
| __ pushq(RBX); // IC data array.
|
| __ pushq(R10); // Arguments descriptor array.
|
| @@ -1545,8 +1543,7 @@
|
| __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
|
|
|
| // IC miss.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| // Compute address of arguments (first read number of arguments from
|
| // arguments descriptor array and then compute address on the stack).
|
| __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
|
| @@ -1554,7 +1551,7 @@
|
| __ EnterStubFrame();
|
| __ pushq(R10); // Preserve arguments descriptor array.
|
| __ pushq(RBX); // Preserve IC data object.
|
| - __ pushq(raw_null); // Setup space on stack for result (target code object).
|
| + __ pushq(R12); // Setup space on stack for result (target code object).
|
| // Push call arguments.
|
| for (intptr_t i = 0; i < num_args; i++) {
|
| __ movq(RCX, Address(RAX, -kWordSize * i));
|
| @@ -1571,7 +1568,7 @@
|
| __ popq(R10); // Restore arguments descriptor array.
|
| __ LeaveFrame();
|
| Label call_target_function;
|
| - __ cmpq(RAX, raw_null);
|
| + __ cmpq(RAX, R12);
|
| __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
|
| // NoSuchMethod or closure.
|
| // Mark IC call that it may be a closure call that does not collect
|
| @@ -1737,13 +1734,12 @@
|
| Immediate(Smi::RawValue(Smi::kMaxValue)));
|
| __ Bind(&increment_done);
|
|
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| Label target_is_compiled;
|
| // Get function and call it, if possible.
|
| __ movq(R13, Address(R12, target_offset));
|
| __ movq(RAX, FieldAddress(R13, Function::code_offset()));
|
| - __ cmpq(RAX, raw_null);
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ cmpq(RAX, R12);
|
| __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
|
|
|
| __ EnterStubFrame();
|
| @@ -1783,9 +1779,8 @@
|
| __ pushq(R10);
|
| // Room for result. Debugger stub returns address of the
|
| // unpatched runtime stub.
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ pushq(raw_null); // Room for result.
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| + __ pushq(R12); // Room for result.
|
| __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
|
| __ popq(RAX); // Address of original.
|
| __ popq(R10); // Restore arguments.
|
| @@ -1798,11 +1793,10 @@
|
| // RBX: ICData (unoptimized static call)
|
| // TOS(0): return address (Dart code).
|
| void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| __ EnterStubFrame();
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| __ pushq(RBX); // Preserve IC data for unoptimized call.
|
| - __ pushq(raw_null); // Room for result.
|
| + __ pushq(R12); // Room for result.
|
| __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0);
|
| __ popq(RAX); // Code object.
|
| __ popq(RBX); // Restore IC data.
|
| @@ -1827,7 +1821,7 @@
|
| __ LeaveFrame();
|
|
|
| __ popq(R11); // discard return address of call to this stub.
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
| __ ret();
|
| }
|
|
|
| @@ -1868,17 +1862,16 @@
|
| // Result in RCX: null -> not found, otherwise result (true or false).
|
| static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
|
| ASSERT((1 <= n) && (n <= 3));
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
|
| const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
|
| const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
|
| __ movq(RAX, Address(RSP, kInstanceOffsetInBytes));
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| if (n > 1) {
|
| __ LoadClass(R10, RAX);
|
| // Compute instance type arguments into R13.
|
| Label has_no_type_arguments;
|
| - __ movq(R13, raw_null);
|
| + __ movq(R13, R12);
|
| __ movq(RDI, FieldAddress(R10,
|
| Class::type_arguments_field_offset_in_words_offset()));
|
| __ cmpq(RDI, Immediate(Class::kNoTypeArguments));
|
| @@ -1900,7 +1893,7 @@
|
| __ SmiTag(R10);
|
| __ Bind(&loop);
|
| __ movq(RDI, Address(RDX, kWordSize * SubtypeTestCache::kInstanceClassId));
|
| - __ cmpq(RDI, raw_null);
|
| + __ cmpq(RDI, R12);
|
| __ j(EQUAL, ¬_found, Assembler::kNearJump);
|
| __ cmpq(RDI, R10);
|
| if (n == 1) {
|
| @@ -1927,7 +1920,7 @@
|
| __ jmp(&loop, Assembler::kNearJump);
|
| // Fall through to not found.
|
| __ Bind(¬_found);
|
| - __ movq(RCX, raw_null);
|
| + __ movq(RCX, R12);
|
| __ ret();
|
|
|
| __ Bind(&found);
|
| @@ -2060,10 +2053,10 @@
|
| __ movq(RAX, Address(RSP, 1 * kWordSize));
|
| __ cmpq(RAX, Address(RSP, 2 * kWordSize));
|
| __ j(EQUAL, &true_label, Assembler::kNearJump);
|
| - __ LoadObject(RAX, Bool::False());
|
| + __ LoadObject(RAX, Bool::False(), PP);
|
| __ ret();
|
| __ Bind(&true_label);
|
| - __ LoadObject(RAX, Bool::True());
|
| + __ LoadObject(RAX, Bool::True(), PP);
|
| __ ret();
|
|
|
| __ Bind(&get_class_id_as_smi);
|
| @@ -2081,7 +2074,7 @@
|
|
|
| __ Bind(&update_ic_data);
|
|
|
| - // RCX: ICData
|
| + // RBX: ICData
|
| __ movq(RAX, Address(RSP, 1 * kWordSize));
|
| __ movq(R13, Address(RSP, 2 * kWordSize));
|
| __ EnterStubFrame();
|
| @@ -2100,11 +2093,10 @@
|
| // RDI: function to be reoptimized.
|
| // R10: argument descriptor (preserved).
|
| void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
|
| - const Immediate& raw_null =
|
| - Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| - __ EnterStubFrame();
|
| + __ EnterStubFrameWithPP();
|
| + __ LoadObject(R12, Object::Handle(), PP);
|
| __ pushq(R10);
|
| - __ pushq(raw_null); // Setup space on stack for return value.
|
| + __ pushq(R12); // Setup space on stack for return value.
|
| __ pushq(RDI);
|
| __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
|
| __ popq(RAX); // Disard argument.
|
| @@ -2112,7 +2104,7 @@
|
| __ popq(R10); // Restore argument descriptor.
|
| __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
|
| __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
|
| - __ LeaveFrame();
|
| + __ LeaveFrameWithPP();
|
| __ jmp(RAX);
|
| __ int3();
|
| }
|
|
|