Skip to content

Commit 633c538

Browse files
dcharkescommit-bot@chromium.org
authored andcommitted
[vm/ffi] Document shadow space and restore RSP
Split off from https://dart-review.googlesource.com/c/sdk/+/140290. We start using the stack after the C call, so RSP needs to be restored. Issue #36730. TEST=All existing FFI tests on windows. Change-Id: Idcaff9007c1b6f42b95288e39470b3d6cca2ef56 Cq-Include-Trybots: luci.dart.try:vm-kernel-win-debug-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170425 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Daco Harkes <[email protected]>
1 parent b1946a5 commit 633c538

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

runtime/vm/compiler/assembler/assembler_x64.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,19 +1671,27 @@ void Assembler::LeaveCallRuntimeFrame() {
16711671
LeaveStubFrame();
16721672
}
16731673

1674-
void Assembler::CallCFunction(Register reg) {
1674+
void Assembler::CallCFunction(Register reg, bool restore_rsp) {
16751675
// Reserve shadow space for outgoing arguments.
16761676
if (CallingConventions::kShadowSpaceBytes != 0) {
16771677
subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
16781678
}
16791679
call(reg);
1680+
// Restore stack.
1681+
if (restore_rsp && CallingConventions::kShadowSpaceBytes != 0) {
1682+
addq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
1683+
}
16801684
}
1681-
void Assembler::CallCFunction(Address address) {
1685+
void Assembler::CallCFunction(Address address, bool restore_rsp) {
16821686
// Reserve shadow space for outgoing arguments.
16831687
if (CallingConventions::kShadowSpaceBytes != 0) {
16841688
subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
16851689
}
16861690
call(address);
1691+
// Restore stack.
1692+
if (restore_rsp && CallingConventions::kShadowSpaceBytes != 0) {
1693+
addq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
1694+
}
16871695
}
16881696

16891697
void Assembler::CallRuntime(const RuntimeEntry& entry,

runtime/vm/compiler/assembler/assembler_x64.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,9 +829,9 @@ class Assembler : public AssemblerBase {
829829
void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
830830

831831
// Call runtime function. Reserves shadow space on the stack before calling
832-
// if platform ABI requires that. Does not restore RSP after the call itself.
833-
void CallCFunction(Register reg);
834-
void CallCFunction(Address address);
832+
// if platform ABI requires that.
833+
void CallCFunction(Register reg, bool restore_rsp = false);
834+
void CallCFunction(Address address, bool restore_rsp = false);
835835

836836
void ExtractClassIdFromTags(Register result, Register tags);
837837
void ExtractInstanceSizeFromTags(Register result, Register tags);

runtime/vm/compiler/backend/il_x64.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
10821082
__ TransitionGeneratedToNative(target_address, FPREG, TMP,
10831083
/*enter_safepoint=*/true);
10841084

1085-
__ CallCFunction(target_address);
1085+
__ CallCFunction(target_address, /*restore_rsp=*/true);
10861086

10871087
// Update information in the thread object and leave the safepoint.
10881088
__ TransitionNativeToGenerated(/*leave_safepoint=*/true);

runtime/vm/compiler/stub_code_compiler_x64.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
282282
/*enter_safepoint=*/true);
283283

284284
__ popq(R12);
285-
__ CallCFunction(RBX);
285+
__ CallCFunction(RBX, /*restore_rsp=*/true);
286286

287287
__ TransitionNativeToGenerated(/*leave_safepoint=*/true);
288288

runtime/vm/constants_x64.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,16 @@ class CallingConventions {
304304
// same time? (Windows no, rest yes)
305305
static const bool kArgumentIntRegXorFpuReg = true;
306306

307+
// > The x64 Application Binary Interface (ABI) uses a four-register
308+
// > fast-call calling convention by default. Space is allocated on the call
309+
// > stack as a shadow store for callees to save those registers.
310+
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
311+
//
312+
// The caller allocates this space. The caller should also reclaim this space
313+
// after the call to restore the stack to its original state if needed.
314+
//
315+
// This is also known as home space.
316+
// https://devblogs.microsoft.com/oldnewthing/20160623-00/?p=93735
307317
static const intptr_t kShadowSpaceBytes = 4 * kWordSize;
308318

309319
static const intptr_t kVolatileCpuRegisters =

0 commit comments

Comments
 (0)