-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Unnecessary padding in struct field auto layout #59593
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
The remarks section of the You can use |
In particular, the managed layout for nested value type fields looks to force an alignment of #if !defined(TARGET_64BIT) && (DATA_ALIGNMENT > 4)
dwCumulativeInstanceFieldPos = (DWORD)ALIGN_UP(dwCumulativeInstanceFieldPos,
(pByValueMT->GetNumInstanceFieldBytes() >= DATA_ALIGNMENT) ? DATA_ALIGNMENT : TARGET_POINTER_SIZE);
#else // !(!defined(TARGET_64BIT) && (DATA_ALIGNMENT > 4))
#ifdef FEATURE_64BIT_ALIGNMENT
if (pByValueMT->RequiresAlign8())
dwCumulativeInstanceFieldPos = (DWORD)ALIGN_UP(dwCumulativeInstanceFieldPos, 8);
else
#endif // FEATURE_64BIT_ALIGNMENT
dwCumulativeInstanceFieldPos = (DWORD)ALIGN_UP(dwCumulativeInstanceFieldPos, TARGET_POINTER_SIZE);
#endif // !(!defined(TARGET_64BIT) && (DATA_ALIGNMENT > 4)) @jkotas, do you know why we do this rather than looking up the |
This looks similar to #12977. The field layout has number of corner cases that are either inefficient or too complex for no good reason. @trylek tried to clean it up in #51416, but we run out of time. If you touch field layout, a lot of random things start falling apart. I hope we will get it done in .NET 7. |
@trylek @jkoritzinsky assume this is fixed as part of the type layout work in 7? |
This has been mitigated as part of the layout work, but it hasn't entirely been fixed. Here's the report from ObjectLayoutInspector from Preview 6: Details
As you can see, TestSize4 is now 16 bytes, and TestSize2 has shrunk to 24 bytes. TestSize2 is still 24 bytes because of how the auto-layout algorithm handles non-primitive struct types. The auto-layout algorithm always handles non-primitive value types last and places them in metadata order at the end of the structure. This results in the TestSize2 struct being larger because even empty structs are 1 byte wide, so there ends up being quite a bit of padding at the end of the structure to meet the alignment requirements in arrays. Changing how the auto-layout algorithm handles value types of small sizes is likely a larger change (and more of a feature than a bug), so I don't know if we should try to fix this in .NET 7 given how late we are in the release. |
While @jkotas previously suggested we should strive to fix as many issues of this type as we can in .NET 7, changing the auto layout now sounds pretty scary to me (not mentioning it's a coordinated change between CoreCLR runtime and Crossgen2 that also requires bumping up Crossgen2 major version). |
I agree that this looks like a feature, not a bug fix. We can get to it during the next field layout overhaul. |
Description
object
andnint
should have identical size and alignement when used as fields. However, in some cases, changing anobject
field intonint
changes the struct size. This problem is also related to other fields in the struct.On 64-bit platform, TestSize1-4 should all have the same size of 16 bytes (2 pointers), but some extend into 32 bytes.
Configuration
Windows 10.0.19043.1165 (21H1/May2021Update)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.100-preview.7.21379.14
Regression?
.NET 5 shows the same results.
The text was updated successfully, but these errors were encountered: