Skip to content

Commit c0b938c

Browse files
dcharkesCommit Queue
authored and
Commit Queue
committed
[vm/ffi] Fix variadic arguments on MacOS Arm64
Non-variadic arguments on the stack on MacOS Arm64 are aligned to the value size (which can be smaller than word size). However, for varargs, the arguments on the stack seem to be aligned to the word size. This CL introduces an alignment strategy constant for primitives on the stack in varargs and uses it in the native calling convention calculation. TEST=runtime/vm/compiler/ffi/native_calling_convention_test.cc with runtime/vm/compiler/ffi/unit_tests/variadic_less_than_word/arm64_macos.expect TEST=tests/ffi/function_varargs_generated_native_leaf_test.dart Closes: #55471 Change-Id: I51d20c3933a2cea9b110954ddec92fb91b9c3ecd Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362762 Commit-Queue: Daco Harkes <[email protected]> Reviewed-by: Tess Strickland <[email protected]>
1 parent 4bb644c commit c0b938c

35 files changed

+685
-2
lines changed

runtime/bin/ffi_test/ffi_test_functions_generated.cc

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22996,6 +22996,38 @@ DART_EXPORT int64_t VariadicAt1Int64x7Struct12BytesHomogeneousInt32(int64_t a0,
2299622996
return result;
2299722997
}
2299822998

22999+
// Used for testing structs and unions by value.
23000+
// Variadic arguments test on macos_arm64.
23001+
DART_EXPORT int32_t VariadicAt1Struct12BytesHomogeneousInt32Int32x4(
23002+
Struct12BytesHomogeneousInt32 a0,
23003+
...) {
23004+
va_list var_args;
23005+
va_start(var_args, a0);
23006+
int32_t a1 = va_arg(var_args, int32_t);
23007+
int32_t a2 = va_arg(var_args, int32_t);
23008+
int32_t a3 = va_arg(var_args, int32_t);
23009+
int32_t a4 = va_arg(var_args, int32_t);
23010+
va_end(var_args);
23011+
23012+
std::cout << "VariadicAt1Struct12BytesHomogeneousInt32Int32x4" << "(("
23013+
<< a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), " << a1 << ", "
23014+
<< a2 << ", " << a3 << ", " << a4 << ")" << "\n";
23015+
23016+
int32_t result = 0;
23017+
23018+
result += a0.a0;
23019+
result += a0.a1;
23020+
result += a0.a2;
23021+
result += a1;
23022+
result += a2;
23023+
result += a3;
23024+
result += a4;
23025+
23026+
std::cout << "result = " << result << "\n";
23027+
23028+
return result;
23029+
}
23030+
2299923031
// Used for testing structs and unions by value.
2300023032
// Single variadic argument.
2300123033
DART_EXPORT intptr_t TestVariadicAt1Int64x2(
@@ -23897,4 +23929,50 @@ DART_EXPORT intptr_t TestVariadicAt1Int64x7Struct12BytesHomogeneousInt32(
2389723929
return 0;
2389823930
}
2389923931

23932+
// Used for testing structs and unions by value.
23933+
// Variadic arguments test on macos_arm64.
23934+
DART_EXPORT intptr_t TestVariadicAt1Struct12BytesHomogeneousInt32Int32x4(
23935+
// NOLINTNEXTLINE(whitespace/parens)
23936+
int32_t (*f)(Struct12BytesHomogeneousInt32 a0, ...)) {
23937+
Struct12BytesHomogeneousInt32 a0 = {};
23938+
int32_t a1;
23939+
int32_t a2;
23940+
int32_t a3;
23941+
int32_t a4;
23942+
23943+
a0.a0 = -1;
23944+
a0.a1 = 2;
23945+
a0.a2 = -3;
23946+
a1 = 4;
23947+
a2 = -5;
23948+
a3 = 6;
23949+
a4 = -7;
23950+
23951+
std::cout << "Calling TestVariadicAt1Struct12BytesHomogeneousInt32Int32x4("
23952+
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), " << a1
23953+
<< ", " << a2 << ", " << a3 << ", " << a4 << ")" << ")\n";
23954+
23955+
int32_t result = f(a0, a1, a2, a3, a4);
23956+
23957+
std::cout << "result = " << result << "\n";
23958+
23959+
CHECK_EQ(-4, result);
23960+
23961+
// Pass argument that will make the Dart callback throw.
23962+
a0.a0 = 42;
23963+
23964+
result = f(a0, a1, a2, a3, a4);
23965+
23966+
CHECK_EQ(0, result);
23967+
23968+
// Pass argument that will make the Dart callback return null.
23969+
a0.a0 = 84;
23970+
23971+
result = f(a0, a1, a2, a3, a4);
23972+
23973+
CHECK_EQ(0, result);
23974+
23975+
return 0;
23976+
}
23977+
2390023978
} // namespace dart

runtime/vm/compiler/ffi/native_calling_convention.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ class ArgumentAllocator : public ValueObject {
242242
zone_, payload_type, container_type, AllocateCpuRegister());
243243
}
244244
}
245-
return AllocateStack(payload_type);
245+
return AllocateStack(payload_type, is_vararg);
246246
}
247247

248248
// Constructs a container type.

runtime/vm/compiler/ffi/native_calling_convention_test.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,28 @@ UNIT_TEST_CASE_WITH_ZONE(
969969
RunSignatureTest(Z, "variadic_stradle_last_register", native_signature);
970970
}
971971

972+
// Struct parameter that potentially is partially allocated to a register and
973+
// partially to the stack. Mainly interesting on ARM64 and RISC-V.
974+
//
975+
// See the *.expect in ./unit_tests for this behavior.
976+
UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_variadic_less_than_word) {
977+
#if defined(TARGET_ARCH_IS_32_BIT)
978+
const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt16);
979+
#elif defined(TARGET_ARCH_IS_64_BIT)
980+
const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt32);
981+
#endif
982+
983+
auto& arguments = *new (Z) NativeTypes(Z, 12);
984+
for (intptr_t i = 0; i < 12; i++) {
985+
arguments.Add(&halfptr_type);
986+
}
987+
988+
const auto& native_signature = *new (Z) NativeFunctionType(
989+
arguments, halfptr_type, /*variadic_arguments_index=*/1);
990+
991+
RunSignatureTest(Z, "variadic_less_than_word", native_signature);
992+
}
993+
972994
} // namespace ffi
973995
} // namespace compiler
974996
} // namespace dart

runtime/vm/compiler/ffi/native_type.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ intptr_t NativePrimitiveType::SizeInBytes() const {
152152
}
153153

154154
intptr_t NativePrimitiveType::AlignmentInBytesStack(bool is_vararg) const {
155-
switch (CallingConventions::kArgumentStackAlignment) {
155+
const auto alignment =
156+
is_vararg ? CallingConventions::kArgumentStackAlignmentVarArgs
157+
: CallingConventions::kArgumentStackAlignment;
158+
switch (alignment) {
156159
case kAlignedToWordSize:
157160
// The default is to align stack arguments to word size.
158161
return compiler::target::kWordSize;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
r1 int32
3+
r2 int32
4+
r3 int32
5+
r4 int32
6+
r5 int32
7+
r6 int32
8+
r7 int32
9+
S+0 int32
10+
S+8 int32
11+
S+16 int32
12+
S+24 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
r1 int32
3+
r2 int32
4+
r3 int32
5+
r4 int32
6+
r5 int32
7+
r6 int32
8+
r7 int32
9+
S+0 int32
10+
S+8 int32
11+
S+16 int32
12+
S+24 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
S+0 int32
3+
S+8 int32
4+
S+16 int32
5+
S+24 int32
6+
S+32 int32
7+
S+40 int32
8+
S+48 int32
9+
S+56 int32
10+
S+64 int32
11+
S+72 int32
12+
S+80 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
r1 int32
3+
r2 int32
4+
r3 int32
5+
r4 int32
6+
r5 int32
7+
r6 int32
8+
r7 int32
9+
S+0 int32
10+
S+8 int32
11+
S+16 int32
12+
S+24 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
S+0 int32
3+
S+8 int32
4+
S+16 int32
5+
S+24 int32
6+
S+32 int32
7+
S+40 int32
8+
S+48 int32
9+
S+56 int32
10+
S+64 int32
11+
S+72 int32
12+
S+80 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32
2+
r1 int32
3+
r2 int32
4+
r3 int32
5+
r4 int32
6+
r5 int32
7+
r6 int32
8+
r7 int32
9+
S+0 int32
10+
S+8 int32
11+
S+16 int32
12+
S+24 int32
13+
=>
14+
r0 int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32[int16]
2+
r1 int32[int16]
3+
r2 int32[int16]
4+
r3 int32[int16]
5+
S+0 int32[int16]
6+
S+4 int32[int16]
7+
S+8 int32[int16]
8+
S+12 int32[int16]
9+
S+16 int32[int16]
10+
S+20 int32[int16]
11+
S+24 int32[int16]
12+
S+28 int32[int16]
13+
=>
14+
r0 int32[int16]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32[int16]
2+
r1 int32[int16]
3+
r2 int32[int16]
4+
r3 int32[int16]
5+
S+0 int32[int16]
6+
S+4 int32[int16]
7+
S+8 int32[int16]
8+
S+12 int32[int16]
9+
S+16 int32[int16]
10+
S+20 int32[int16]
11+
S+24 int32[int16]
12+
S+28 int32[int16]
13+
=>
14+
r0 int32[int16]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
r0 int32[int16]
2+
r1 int32[int16]
3+
r2 int32[int16]
4+
r3 int32[int16]
5+
S+0 int32[int16]
6+
S+4 int32[int16]
7+
S+8 int32[int16]
8+
S+12 int32[int16]
9+
S+16 int32[int16]
10+
S+20 int32[int16]
11+
S+24 int32[int16]
12+
S+28 int32[int16]
13+
=>
14+
r0 int32[int16]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
S+0 int32[int16]
2+
S+4 int32[int16]
3+
S+8 int32[int16]
4+
S+12 int32[int16]
5+
S+16 int32[int16]
6+
S+20 int32[int16]
7+
S+24 int32[int16]
8+
S+28 int32[int16]
9+
S+32 int32[int16]
10+
S+36 int32[int16]
11+
S+40 int32[int16]
12+
S+44 int32[int16]
13+
=>
14+
eax int16
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
S+0 int32[int16]
2+
S+4 int32[int16]
3+
S+8 int32[int16]
4+
S+12 int32[int16]
5+
S+16 int32[int16]
6+
S+20 int32[int16]
7+
S+24 int32[int16]
8+
S+28 int32[int16]
9+
S+32 int32[int16]
10+
S+36 int32[int16]
11+
S+40 int32[int16]
12+
S+44 int32[int16]
13+
=>
14+
eax int16
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
S+0 int32[int16]
2+
S+4 int32[int16]
3+
S+8 int32[int16]
4+
S+12 int32[int16]
5+
S+16 int32[int16]
6+
S+20 int32[int16]
7+
S+24 int32[int16]
8+
S+28 int32[int16]
9+
S+32 int32[int16]
10+
S+36 int32[int16]
11+
S+40 int32[int16]
12+
S+44 int32[int16]
13+
=>
14+
eax int16
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
a0 int32[int16]
2+
a1 int32[int16]
3+
a2 int32[int16]
4+
t3 int32[int16]
5+
t4 int32[int16]
6+
t5 int32[int16]
7+
a6 int32[int16]
8+
a7 int32[int16]
9+
S+0 int32[int16]
10+
S+4 int32[int16]
11+
S+8 int32[int16]
12+
S+12 int32[int16]
13+
=>
14+
a0 int32[int16]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
a0 int64[int32]
2+
a1 int64[int32]
3+
a2 int64[int32]
4+
t3 int64[int32]
5+
t4 int64[int32]
6+
t5 int64[int32]
7+
a6 int64[int32]
8+
a7 int64[int32]
9+
S+0 int64[int32]
10+
S+8 int64[int32]
11+
S+16 int64[int32]
12+
S+24 int64[int32]
13+
=>
14+
a0 int64[int32]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
rdi int32
2+
rsi int32
3+
rdx int32
4+
rcx int32
5+
r8 int32
6+
r9 int32
7+
S+0 int32
8+
S+8 int32
9+
S+16 int32
10+
S+24 int32
11+
S+32 int32
12+
S+40 int32
13+
=>
14+
rax int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
rdi int32
2+
rsi int32
3+
rdx int32
4+
rcx int32
5+
r8 int32
6+
r9 int32
7+
S+0 int32
8+
S+8 int32
9+
S+16 int32
10+
S+24 int32
11+
S+32 int32
12+
S+40 int32
13+
=>
14+
rax int32
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
rdi int32
2+
rsi int32
3+
rdx int32
4+
rcx int32
5+
r8 int32
6+
r9 int32
7+
S+0 int32
8+
S+8 int32
9+
S+16 int32
10+
S+24 int32
11+
S+32 int32
12+
S+40 int32
13+
=>
14+
rax int32

0 commit comments

Comments
 (0)