Skip to content

Commit 6101e46

Browse files
dcharkescommit-bot@chromium.org
authored andcommitted
[test/ffi] Add struct stack alignment test
A smoke test to exercise alignment of structs with various field types to see how they are aligned on the stack. Only contains small structs because most ABIs only pass structs less than 16 bytes on the stack. Especially tests iOS64, where `AlignOf(struct{float32;float32;}) == 4` but `AlignOf(struct{int32;int32;}) == 8` due to the special treatment of homogenous floats in the arm64 ABI combined with iOS decision to not align everything on the stack to at least word size. Test tested on iOS64 through Flutter. structs_by_value_tests_configuration.dart is the only non-generated file. The tests are tested in the dependent CL. Tests are ignored in status file and are un-ignored in dependent CL. Tests for #36730. Change-Id: I6ec4523208db740b8ea3f8a4ab1e5717f1088467 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170691 Commit-Queue: Daco Harkes <[email protected]> Auto-Submit: Daco Harkes <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent d54e2bb commit 6101e46

7 files changed

+1457
-0
lines changed

runtime/bin/ffi_test/ffi_test_functions_generated.cc

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,131 @@ DART_EXPORT double PassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
23862386
return result;
23872387
}
23882388

2389+
// Used for testing structs by value.
2390+
// Test alignment and padding of 16 byte int within struct.
2391+
DART_EXPORT double PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
2392+
int32_t a0,
2393+
int32_t a1,
2394+
int32_t a2,
2395+
int32_t a3,
2396+
int32_t a4,
2397+
int32_t a5,
2398+
int32_t a6,
2399+
int32_t a7,
2400+
double a8,
2401+
double a9,
2402+
double a10,
2403+
double a11,
2404+
double a12,
2405+
double a13,
2406+
double a14,
2407+
double a15,
2408+
int64_t a16,
2409+
int8_t a17,
2410+
Struct1ByteInt a18,
2411+
int64_t a19,
2412+
int8_t a20,
2413+
Struct4BytesHomogeneousInt16 a21,
2414+
int64_t a22,
2415+
int8_t a23,
2416+
Struct8BytesInt a24,
2417+
int64_t a25,
2418+
int8_t a26,
2419+
Struct8BytesHomogeneousFloat a27,
2420+
int64_t a28,
2421+
int8_t a29,
2422+
Struct8BytesMixed a30,
2423+
int64_t a31,
2424+
int8_t a32,
2425+
StructAlignmentInt16 a33,
2426+
int64_t a34,
2427+
int8_t a35,
2428+
StructAlignmentInt32 a36,
2429+
int64_t a37,
2430+
int8_t a38,
2431+
StructAlignmentInt64 a39) {
2432+
std::cout << "PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int"
2433+
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
2434+
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
2435+
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
2436+
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
2437+
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
2438+
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
2439+
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
2440+
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
2441+
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
2442+
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
2443+
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
2444+
<< ", " << static_cast<int>(a32) << ", ("
2445+
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
2446+
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
2447+
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
2448+
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
2449+
<< a37 << ", " << static_cast<int>(a38) << ", ("
2450+
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
2451+
<< static_cast<int>(a39.a2) << "))"
2452+
<< "\n";
2453+
2454+
double result = 0;
2455+
2456+
result += a0;
2457+
result += a1;
2458+
result += a2;
2459+
result += a3;
2460+
result += a4;
2461+
result += a5;
2462+
result += a6;
2463+
result += a7;
2464+
result += a8;
2465+
result += a9;
2466+
result += a10;
2467+
result += a11;
2468+
result += a12;
2469+
result += a13;
2470+
result += a14;
2471+
result += a15;
2472+
result += a16;
2473+
result += a17;
2474+
result += a18.a0;
2475+
result += a19;
2476+
result += a20;
2477+
result += a21.a0;
2478+
result += a21.a1;
2479+
result += a22;
2480+
result += a23;
2481+
result += a24.a0;
2482+
result += a24.a1;
2483+
result += a24.a2;
2484+
result += a25;
2485+
result += a26;
2486+
result += a27.a0;
2487+
result += a27.a1;
2488+
result += a28;
2489+
result += a29;
2490+
result += a30.a0;
2491+
result += a30.a1;
2492+
result += a30.a2;
2493+
result += a31;
2494+
result += a32;
2495+
result += a33.a0;
2496+
result += a33.a1;
2497+
result += a33.a2;
2498+
result += a34;
2499+
result += a35;
2500+
result += a36.a0;
2501+
result += a36.a1;
2502+
result += a36.a2;
2503+
result += a37;
2504+
result += a38;
2505+
result += a39.a0;
2506+
result += a39.a1;
2507+
result += a39.a2;
2508+
2509+
std::cout << "result = " << result << "\n";
2510+
2511+
return result;
2512+
}
2513+
23892514
// Used for testing structs by value.
23902515
// Test alignment and padding of 16 byte int within struct.
23912516
DART_EXPORT int64_t PassStructAlignmentInt16(StructAlignmentInt16 a0) {
@@ -6357,6 +6482,196 @@ DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
63576482
return 0;
63586483
}
63596484

6485+
// Used for testing structs by value.
6486+
// Test alignment and padding of 16 byte int within struct.
6487+
DART_EXPORT intptr_t TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int(
6488+
// NOLINTNEXTLINE(whitespace/parens)
6489+
double (*f)(int32_t a0,
6490+
int32_t a1,
6491+
int32_t a2,
6492+
int32_t a3,
6493+
int32_t a4,
6494+
int32_t a5,
6495+
int32_t a6,
6496+
int32_t a7,
6497+
double a8,
6498+
double a9,
6499+
double a10,
6500+
double a11,
6501+
double a12,
6502+
double a13,
6503+
double a14,
6504+
double a15,
6505+
int64_t a16,
6506+
int8_t a17,
6507+
Struct1ByteInt a18,
6508+
int64_t a19,
6509+
int8_t a20,
6510+
Struct4BytesHomogeneousInt16 a21,
6511+
int64_t a22,
6512+
int8_t a23,
6513+
Struct8BytesInt a24,
6514+
int64_t a25,
6515+
int8_t a26,
6516+
Struct8BytesHomogeneousFloat a27,
6517+
int64_t a28,
6518+
int8_t a29,
6519+
Struct8BytesMixed a30,
6520+
int64_t a31,
6521+
int8_t a32,
6522+
StructAlignmentInt16 a33,
6523+
int64_t a34,
6524+
int8_t a35,
6525+
StructAlignmentInt32 a36,
6526+
int64_t a37,
6527+
int8_t a38,
6528+
StructAlignmentInt64 a39)) {
6529+
int32_t a0;
6530+
int32_t a1;
6531+
int32_t a2;
6532+
int32_t a3;
6533+
int32_t a4;
6534+
int32_t a5;
6535+
int32_t a6;
6536+
int32_t a7;
6537+
double a8;
6538+
double a9;
6539+
double a10;
6540+
double a11;
6541+
double a12;
6542+
double a13;
6543+
double a14;
6544+
double a15;
6545+
int64_t a16;
6546+
int8_t a17;
6547+
Struct1ByteInt a18;
6548+
int64_t a19;
6549+
int8_t a20;
6550+
Struct4BytesHomogeneousInt16 a21;
6551+
int64_t a22;
6552+
int8_t a23;
6553+
Struct8BytesInt a24;
6554+
int64_t a25;
6555+
int8_t a26;
6556+
Struct8BytesHomogeneousFloat a27;
6557+
int64_t a28;
6558+
int8_t a29;
6559+
Struct8BytesMixed a30;
6560+
int64_t a31;
6561+
int8_t a32;
6562+
StructAlignmentInt16 a33;
6563+
int64_t a34;
6564+
int8_t a35;
6565+
StructAlignmentInt32 a36;
6566+
int64_t a37;
6567+
int8_t a38;
6568+
StructAlignmentInt64 a39;
6569+
6570+
a0 = -1;
6571+
a1 = 2;
6572+
a2 = -3;
6573+
a3 = 4;
6574+
a4 = -5;
6575+
a5 = 6;
6576+
a6 = -7;
6577+
a7 = 8;
6578+
a8 = -9.0;
6579+
a9 = 10.0;
6580+
a10 = -11.0;
6581+
a11 = 12.0;
6582+
a12 = -13.0;
6583+
a13 = 14.0;
6584+
a14 = -15.0;
6585+
a15 = 16.0;
6586+
a16 = -17;
6587+
a17 = 18;
6588+
a18.a0 = -19;
6589+
a19 = 20;
6590+
a20 = -21;
6591+
a21.a0 = 22;
6592+
a21.a1 = -23;
6593+
a22 = 24;
6594+
a23 = -25;
6595+
a24.a0 = 26;
6596+
a24.a1 = -27;
6597+
a24.a2 = 28;
6598+
a25 = -29;
6599+
a26 = 30;
6600+
a27.a0 = -31.0;
6601+
a27.a1 = 32.0;
6602+
a28 = -33;
6603+
a29 = 34;
6604+
a30.a0 = -35.0;
6605+
a30.a1 = 36;
6606+
a30.a2 = -37;
6607+
a31 = 38;
6608+
a32 = -39;
6609+
a33.a0 = 40;
6610+
a33.a1 = -41;
6611+
a33.a2 = 42;
6612+
a34 = -43;
6613+
a35 = 44;
6614+
a36.a0 = -45;
6615+
a36.a1 = 46;
6616+
a36.a2 = -47;
6617+
a37 = 48;
6618+
a38 = -49;
6619+
a39.a0 = 50;
6620+
a39.a1 = -51;
6621+
a39.a2 = 52;
6622+
6623+
std::cout << "Calling TestPassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int("
6624+
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
6625+
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
6626+
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
6627+
<< ", " << a14 << ", " << a15 << ", " << a16 << ", "
6628+
<< static_cast<int>(a17) << ", (" << static_cast<int>(a18.a0)
6629+
<< "), " << a19 << ", " << static_cast<int>(a20) << ", (" << a21.a0
6630+
<< ", " << a21.a1 << "), " << a22 << ", " << static_cast<int>(a23)
6631+
<< ", (" << a24.a0 << ", " << a24.a1 << ", " << a24.a2 << "), "
6632+
<< a25 << ", " << static_cast<int>(a26) << ", (" << a27.a0 << ", "
6633+
<< a27.a1 << "), " << a28 << ", " << static_cast<int>(a29) << ", ("
6634+
<< a30.a0 << ", " << a30.a1 << ", " << a30.a2 << "), " << a31
6635+
<< ", " << static_cast<int>(a32) << ", ("
6636+
<< static_cast<int>(a33.a0) << ", " << a33.a1 << ", "
6637+
<< static_cast<int>(a33.a2) << "), " << a34 << ", "
6638+
<< static_cast<int>(a35) << ", (" << static_cast<int>(a36.a0)
6639+
<< ", " << a36.a1 << ", " << static_cast<int>(a36.a2) << "), "
6640+
<< a37 << ", " << static_cast<int>(a38) << ", ("
6641+
<< static_cast<int>(a39.a0) << ", " << a39.a1 << ", "
6642+
<< static_cast<int>(a39.a2) << "))"
6643+
<< ")\n";
6644+
6645+
double result =
6646+
f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
6647+
a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29,
6648+
a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
6649+
6650+
std::cout << "result = " << result << "\n";
6651+
6652+
CHECK_APPROX(26.0, result);
6653+
6654+
// Pass argument that will make the Dart callback throw.
6655+
a0 = 42;
6656+
6657+
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
6658+
a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27,
6659+
a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
6660+
6661+
CHECK_APPROX(0.0, result);
6662+
6663+
// Pass argument that will make the Dart callback return null.
6664+
a0 = 84;
6665+
6666+
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
6667+
a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27,
6668+
a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39);
6669+
6670+
CHECK_APPROX(0.0, result);
6671+
6672+
return 0;
6673+
}
6674+
63606675
// Used for testing structs by value.
63616676
// Test alignment and padding of 16 byte int within struct.
63626677
DART_EXPORT intptr_t TestPassStructAlignmentInt16(

0 commit comments

Comments
 (0)