-
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
46239 v2 (no runtime layout changes) #53424
Conversation
Since we agreed that this is just a stop-gap measure, I think it would better to omit the last commit that introduces a bunch of undesirable dependencies, like making ILVerify depend on interop marshalling. |
@jkotas - Hmm, so am I right to understand that you're suggesting I should basically undo the moves of marshalling-related files originally suggested by Michal and implement the BlittableOrManagedSequential check using a virtual override in ReadyToRunMetadataFieldLayoutAlgorithm? |
I agree with Jan - since having interop intertwined with type layout is not our long term plan per the conversation in the other pull request (and we want to get your other change in after .NET 6 cuts off), it doesn't make sense to move interop into type system just to undo that later this year. |
5ed9f3c
to
1c41aaa
Compare
@@ -349,6 +352,7 @@ protected static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(Metadata | |||
); | |||
if (needsToBeAligned) | |||
{ | |||
largestAlignmentRequired = LayoutInt.Max(largestAlignmentRequired, type.Context.Target.LayoutPointerSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect that ComputeFieldSizeAndAlignment
will return sufficient alignment for GC pointers or anything with GC pointers. Is this really needed? If yes, it would be worth a comment explaining the situation where it is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you're right, I have replaced this with just an assert double-checking that at this point largestAlignmentRequired
must be greater than or equal to PointerSize
.
cumulativeInstanceFieldPos -= offsetBias; | ||
|
||
var layoutMetadata = type.GetClassLayout(); | ||
LayoutInt instanceSize = cumulativeInstanceFieldPos + new LayoutInt(layoutMetadata.Size) + offsetBias; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ComputeInstanceSize
bumps this up to layoutMetadata.Size
again.
I assume that this needs to be here because ComputeInstanceSize
applies it on top of InstanceByteCountUnaligned
, but this one applies it on top InstanceByteCount
? A comment may be useful since this does not make sense by just looking at the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing that out, auditing this aspect has revealed a few rough edges around the base class size calculation; I'm now locally testing an update cleaning this up by consistently using CalculateFieldBaseOffset
in all the relevant places, I'll push the extra commit once I make sure it works reasonably well.
src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
Outdated
Show resolved
Hide resolved
OK, I believe the initial results aren't the worst, the test 46239 still fails on arm but otherwise the Pri1 runs seem mostly clean. I'm working on retesting the change after cleaning up base class size manipulation per JanK's PR feedback and I'm going to look into the arm issue but I believe the change is mostly functional. |
b2497bc
to
87067ae
Compare
The regression test <code>src\tests\JIT\Regressions\JitBlue\Runtime_46239</code> exercises various interesting corner cases of type layout that weren't handled properly in Crossgen2 on x86 and ARM[32]. This change fixes the remaining deficiencies and it also adds provisions for better runtime logging upon type layout mismatches. Thanks Tomas
With this change, the only remaining pipelines using Crossgen1 are "r2r.yml", "r2r-extra.yml" and "release-tests.yml". I haven't yet identified the pipeline running the "release-tests.yml" script; for the "r2r*.yml", these now remain the only pipelines exercising Crossgen1. I don't think it makes sense to switch them over to CG2 as we already have their CG2 counterparts; my expectation is that, once CG1 is finally decommissioned, they will be just deleted. Thanks Tomas
1) Mimic CoreCLR runtime bug filed under dotnet#53542; 2) Fix pointer alignment for byref-like fields.
87067ae
to
3dcdc31
Compare
OK, I finally have a green outerloop run (including the CG2 legs). I believe the change is ready to be merged in. |
LayoutInt cumulativeInstanceFieldPos = CalculateFieldBaseOffset(type, requiresAlign8: false, requiresAlignedBase: false) - offsetBias; | ||
if (!type.IsValueType) | ||
{ | ||
// CoreCLR runtime has a bug in field offset calculation in the presence of class inheritance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a simple repro to demonstrate this bug?
I have tried:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
class A1
{
[FieldOffset(0)]
public int x;
}
[StructLayout(LayoutKind.Explicit)]
class A2 : A1
{
[FieldOffset(0)]
public int y;
}
[StructLayout(LayoutKind.Explicit)]
class A3 : A2
{
[FieldOffset(0)]
public int z;
}
class My
{
static unsafe void Main()
{
A3 a = new A3();
fixed (int *px = &a.x)
fixed (int *pz = &a.z)
{
Console.WriteLine(pz - px);
}
}
}
It prints 2
for me. I would expect it to print more than that given this bug that doubles the base offsets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I modify your example like this:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
class A1
{
[FieldOffset(0)]
public byte x;
[FieldOffset(2)]
public char x2;
}
[StructLayout(LayoutKind.Explicit)]
class A2 : A1
{
[FieldOffset(0)]
public int y;
}
[StructLayout(LayoutKind.Explicit)]
class A3 : A2
{
[FieldOffset(0)]
public byte z;
}
class My
{
static unsafe void Main()
{
A3 a = new A3();
fixed (byte *px = &a.x)
fixed (byte *pz = &a.z)
{
Console.WriteLine(pz - px);
}
}
}
I receive 24; if properly packed, I think it should say 8 like you said. Your example doesn't exhibit the issue because it hits this weird statement I stumbled upon a couple of times when working on the change:
runtime/src/coreclr/vm/methodtablebuilder.cpp
Line 8563 in 01a8f49
if (IsBlittable() || IsManagedSequential()) |
Thanks
Tomas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I should probably add this condition to the quirk, will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I receive 24;
And it prints 19 on .NET Framework and .NET Core 3.1. It looks like we accidentally changing behavior here. @jkoritzinsky Can it be caused by your field layout refactoring? It would be nice to get this fixed and covered by tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I should probably add this condition to the quirk, will do.
I do not think we need to maintain this quirk. I would delete this, disable the test that it hitting this corner case and file a bug to get it fixed. Note that fixing this is not going to be R2R breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly. I think I changed a little bit about how classes with inheritance are considered blittable/non-blittable. That might have changed this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll remove the quirk and I'll retest to see what exactly breaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16c32ae
to
f14893c
Compare
Removal of the quirk naturally hit one of the typesystem tests. I'll fix that once the outerloop tests finish along with any potential additions to issues.targets for tests affected by this issue. |
OK, I have removed the double base size quirk and we're discussing the fix on the issue thread #53542. My previous outerloop testing was green so I'm not planning to run a new outerloop test as that doesn't exercise the Crossgen2 unit testing. Please let me know if there's anything else that needs addressing before merging this long-standing change in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been following this change, and it looks good to me now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM as well. Thank you!
These numbers changed in #53424. One of the reasons why I'm not a huge fan of too much commenting...
Thanks @trylek on fixing this! |
These numbers changed in #53424. One of the reasons why I'm not a huge fan of too much commenting...
This is a simplified version of my original fix for 46239 as the full fix including runtime layout cleanup,
#51416
has an enormous bug tail and seems too risky to take relatively late in the release cycle.
Thanks
Tomas
/cc @dotnet/crossgen-contrib