| Index: runtime/vm/stub_code_arm64.cc
|
| ===================================================================
|
| --- runtime/vm/stub_code_arm64.cc (revision 36919)
|
| +++ runtime/vm/stub_code_arm64.cc (working copy)
|
| @@ -51,8 +51,7 @@
|
|
|
| // Save exit frame information to enable stack walking as we are about
|
| // to transition to Dart VM C++ code.
|
| - __ mov(TMP, SP); // Can't directly store SP.
|
| - __ StoreToOffset(TMP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
| + __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
|
|
| // Save current Context pointer into Isolate structure.
|
| __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
|
| @@ -77,8 +76,9 @@
|
| // Reserve space for arguments and align frame before entering C++ world.
|
| // NativeArguments are passed in registers.
|
| __ Comment("align stack");
|
| + // Reserve space for arguments.
|
| ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
|
| - __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments.
|
| + __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
|
|
|
| // Pass NativeArguments structure by value and call runtime.
|
| // Registers R0, R1, R2, and R3 are used.
|
| @@ -101,12 +101,26 @@
|
| ASSERT(retval_offset == 3 * kWordSize);
|
| __ AddImmediate(R3, R2, kWordSize, kNoPP);
|
|
|
| - // TODO(zra): Check that the ABI allows calling through this register.
|
| + __ StoreToOffset(R0, SP, isolate_offset, kNoPP);
|
| + __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP);
|
| + __ StoreToOffset(R2, SP, argv_offset, kNoPP);
|
| + __ StoreToOffset(R3, SP, retval_offset, kNoPP);
|
| + __ mov(R0, SP); // Pass the pointer to the NativeArguments.
|
| +
|
| + // We are entering runtime code, so the C stack pointer must be restored from
|
| + // the stack limit to the top of the stack. We cache the stack limit address
|
| + // in a callee-saved register.
|
| + __ mov(R26, CSP);
|
| + __ mov(CSP, SP);
|
| +
|
| __ blr(R5);
|
| + __ Comment("CallToRuntimeStub return");
|
|
|
| + // Restore SP and CSP.
|
| + __ mov(SP, CSP);
|
| + __ mov(CSP, R26);
|
| +
|
| // Retval is next to 1st argument.
|
| - __ Comment("CallToRuntimeStub return");
|
| -
|
| // Mark that the isolate is executing Dart code.
|
| __ LoadImmediate(R2, VMTag::kScriptTagId, kNoPP);
|
| __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP);
|
| @@ -155,8 +169,7 @@
|
|
|
| // Save exit frame information to enable stack walking as we are about
|
| // to transition to native code.
|
| - __ mov(TMP, SP);
|
| - __ StoreToOffset(TMP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
| + __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
|
|
| // Save current Context pointer into Isolate structure.
|
| __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
|
| @@ -210,6 +223,12 @@
|
| __ StoreToOffset(R3, SP, retval_offset, kNoPP);
|
| __ mov(R0, SP); // Pass the pointer to the NativeArguments.
|
|
|
| + // We are entering runtime code, so the C stack pointer must be restored from
|
| + // the stack limit to the top of the stack. We cache the stack limit address
|
| + // in the Dart SP register, which is callee-saved in the C ABI.
|
| + __ mov(R26, CSP);
|
| + __ mov(CSP, SP);
|
| +
|
| // Call native function (setsup scope if not leaf function).
|
| Label leaf_call;
|
| Label done;
|
| @@ -234,6 +253,9 @@
|
| __ blr(R5);
|
|
|
| __ Bind(&done);
|
| + // Restore SP and CSP.
|
| + __ mov(SP, CSP);
|
| + __ mov(CSP, R26);
|
|
|
| // Mark that the isolate is executing Dart code.
|
| __ LoadImmediate(R2, VMTag::kScriptTagId, kNoPP);
|
| @@ -276,8 +298,7 @@
|
|
|
| // Save exit frame information to enable stack walking as we are about
|
| // to transition to native code.
|
| - __ mov(TMP, SP); // Can't store SP directly, first copy to TMP.
|
| - __ StoreToOffset(TMP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
| + __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
|
|
|
| // Save current Context pointer into Isolate structure.
|
| __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
|
| @@ -331,9 +352,19 @@
|
| __ StoreToOffset(R3, SP, retval_offset, kNoPP);
|
| __ mov(R0, SP); // Pass the pointer to the NativeArguments.
|
|
|
| + // We are entering runtime code, so the C stack pointer must be restored from
|
| + // the stack limit to the top of the stack. We cache the stack limit address
|
| + // in the Dart SP register, which is callee-saved in the C ABI.
|
| + __ mov(R26, CSP);
|
| + __ mov(CSP, SP);
|
| +
|
| // Call native function or redirection via simulator.
|
| __ blr(R5);
|
|
|
| + // Restore SP and CSP.
|
| + __ mov(SP, CSP);
|
| + __ mov(CSP, R26);
|
| +
|
| // Mark that the isolate is executing Dart code.
|
| __ LoadImmediate(R2, VMTag::kScriptTagId, kNoPP);
|
| __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP);
|
| @@ -487,9 +518,7 @@
|
|
|
| for (intptr_t reg_idx = kNumberOfVRegisters - 1; reg_idx >= 0; reg_idx--) {
|
| VRegister vreg = static_cast<VRegister>(reg_idx);
|
| - // TODO(zra): Save whole V registers. For now, push twice.
|
| - __ PushDouble(vreg);
|
| - __ PushDouble(vreg);
|
| + __ PushQuad(vreg);
|
| }
|
|
|
| __ mov(R0, SP); // Pass address of saved registers block.
|
| @@ -504,8 +533,7 @@
|
|
|
| // There is a Dart Frame on the stack. We must restore PP and leave frame.
|
| __ LeaveDartFrame();
|
| - __ sub(TMP, FP, Operand(R0));
|
| - __ mov(SP, TMP);
|
| + __ sub(SP, FP, Operand(R0));
|
|
|
| // 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.
|
| @@ -547,8 +575,7 @@
|
| }
|
| __ LeaveStubFrame();
|
| // Remove materialization arguments.
|
| - __ add(TMP, SP, Operand(R1, UXTX, 0));
|
| - __ mov(SP, TMP);
|
| + __ add(SP, SP, Operand(R1));
|
| __ ret();
|
| }
|
|
|
| @@ -748,6 +775,9 @@
|
| // R3 : new context containing the current isolate pointer.
|
| void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
| __ Comment("InvokeDartCodeStub");
|
| + // Copy the C stack pointer (R31) into the stack pointer we'll actually use
|
| + // to access the stack.
|
| + __ mov(SP, CSP);
|
| __ EnterFrame(0);
|
|
|
| // The new context, saved vm tag, the top exit frame, and the old context.
|
| @@ -786,9 +816,15 @@
|
| // Cache the new Context pointer into CTX while executing Dart code.
|
| __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle, PP);
|
|
|
| - // Load Isolate pointer from Context structure into temporary register R4.
|
| + // Load Isolate pointer from Context structure into temporary register R5.
|
| __ LoadFieldFromOffset(R5, CTX, Context::isolate_offset(), PP);
|
|
|
| + // Load the stack limit address into the C stack pointer register.
|
| + __ LoadFromOffset(CSP, R5, Isolate::stack_limit_offset(), PP);
|
| +
|
| + // Cache the new Context pointer into CTX while executing Dart code.
|
| + __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle, PP);
|
| +
|
| // Save the current VMTag on the stack.
|
| ASSERT(kSavedVMTagSlotFromEntryFp == -20);
|
| __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP);
|
| @@ -884,12 +920,14 @@
|
| Register r = static_cast<Register>(i);
|
| // We use ldr instead of the Pop macro because we will be popping the PP
|
| // register when it is not holding a pool-pointer since we are returning to
|
| - // C++ code.
|
| + // C++ code. We also skip the dart stack pointer SP, since we are still
|
| + // using it as the stack pointer.
|
| __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex));
|
| }
|
|
|
| - // Restore the frame pointer and return.
|
| + // Restore the frame pointer and C stack pointer and return.
|
| __ LeaveFrame();
|
| + __ mov(CSP, SP);
|
| __ ret();
|
| }
|
|
|
| @@ -1786,7 +1824,8 @@
|
|
|
|
|
| void StubCode::GenerateGetStackPointerStub(Assembler* assembler) {
|
| - __ Stop("GenerateGetStackPointerStub");
|
| + __ mov(R0, SP);
|
| + __ ret();
|
| }
|
|
|
|
|
|
|