Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Force Mono to respect explicit struct size when LayoutKind.Sequential is used #101529

Merged

Conversation

matouskozak
Copy link
Member

@matouskozak matouskozak commented Apr 25, 2024

We encountered an issue with Mono not respecting explicit size when LayoutKind.Sequential was used (#101432). We fix this by eliminating addition of alignment padding when explicit size is set.

@matouskozak matouskozak added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Apr 25, 2024
@matouskozak matouskozak force-pushed the mono/sequential-layout-explicit-size branch from ef2083b to 18e622f Compare April 25, 2024 09:20
@matouskozak
Copy link
Member Author

/azp run runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lambdageek
Copy link
Member

@grendello @jonpryor @lewing @rolfbjarne @dalexsoto We're going to change mono to respect the explicit Size property on a [StructLayout(LayoutKind.Sequential, Size=NN)] attribute, if given, for sequential layouts. (It was already respected for Explicit layouts).

Previously Mono would align the struct size up to the alignment of the most restricted struct element. This was so that arrays would always have their elements such that every struct member would be at its natural alignment. But as a result, if you had a struct inside another struct followed by a member with a less restricted alignment there would always be padding after the struct. So we would behave as if the Size property was always rounded up. CoreCLR doesn't do that. If a Size is given, it will always use it - even if it means that arrays of structs will end up with misaligned members in some elements.

This is needed for Swift interop (frozen swift structs also behave this way). (See #101432)

For example:

[StructLayout(Sequential, Size=12)]
struct DoubleAndInt1
{
   public double D1;
   public int I2;
};

[StructLayout(Sequential)]
struct DoubleAndInt2
{
   public double D1;
   public double I2;
}

Previously in Mono both DoubleAndInt1 and DoubleAndInt2 would have size 16 (12 rounded up to the alignment of the most restricted member - D1). In CoreCLR and in Mono after this change, DoubleAndInt1 will have size 12.

That means if you do a1 = new DoubleAndInt1[2] and a2 = new DoubleAndInt2[2], then a1[1].D1 will be mis-aligned (it will be at offset 12 from the start of a1, while a2[1].D1 will be at its natural alignment (offset 16 from the start of a2).

We're running a functional test on Android arm32 to check whether we need to do some work in the JIT in order to issue an unaligned load/store for arrays like a1

Questions

Is this change going to be a problem for your existing interop code in XI, XA or wasm?

@grendello
Copy link
Contributor

I didn't find any StructLayout use with explicit size in XA code (in-repo or generated), so we should be fine with that change.

LibZipSharp is fine too, however Mono.Posix has one instance which might be affected?

@rolfbjarne
Copy link
Member

Is this change going to be a problem for your existing interop code in XI, XA or wasm?

XI doesn't have any sequential StructLayouts with explicit size, so it's good on our side.

Additionally we use CoreCLR for macOS, and we haven't found any such issues there.

@matouskozak
Copy link
Member Author

LibZipSharp is fine too, however Mono.Posix has one instance which might be affected?

That one should be unaffected by this PR. Here we only modify the behavior for LayoutKind.Sequential. LayoutKind.Explicit was already handled correctly when used together with explicit size.

@lewing
Copy link
Member

lewing commented Apr 25, 2024

I'm not aware of any issues on the wasm side

@matouskozak matouskozak force-pushed the mono/sequential-layout-explicit-size branch from 18e622f to 66272bb Compare April 26, 2024 15:36
@matouskozak matouskozak changed the title [WIP][mono] Force Mono to respect explicit struct size when LayoutKind.Sequential is used [mono] Force Mono to respect explicit struct size when LayoutKind.Sequential is used Apr 26, 2024
@matouskozak
Copy link
Member Author

matouskozak commented Apr 26, 2024

We have tested this change on Arm64 VMs emulating Arm32 without any issues. We also performed successful local testing on armv7 Raspberry (thanks to @akoeplinger).

Copy link
Member

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

@matouskozak
Copy link
Member Author

/azp run runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@matouskozak
Copy link
Member Author

The WASM failures are unrelated and are matched using Build Analysis. The tvos-arm64 Release AllSubsets_Mono Tar failure is also known #101692.

@matouskozak matouskozak merged commit fc09b22 into dotnet:main Apr 30, 2024
153 of 161 checks passed
matouskozak added a commit to matouskozak/runtime that referenced this pull request Apr 30, 2024
…uential is used (dotnet#101529)

* respect explicit size with sequential layout

* test for sequential layout with explicit size
michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
…uential is used (dotnet#101529)

* respect explicit size with sequential layout

* test for sequential layout with explicit size
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
…uential is used (dotnet#101529)

* respect explicit size with sequential layout

* test for sequential layout with explicit size
@github-actions github-actions bot locked and limited conversation to collaborators May 31, 2024
@matouskozak matouskozak deleted the mono/sequential-layout-explicit-size branch October 3, 2024 13:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VM-meta-mono NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants