Fix field offset computation in crossgen2 (dotnet/coreclr#27245)
authorJan Vorlicek <janvorli@microsoft.com>
Thu, 17 Oct 2019 03:43:09 +0000 (05:43 +0200)
committerJan Kotas <jkotas@microsoft.com>
Thu, 17 Oct 2019 03:43:09 +0000 (20:43 -0700)
The logic for determining when to align base offset was not matching the
logic that is used in the coreclr runtime. This resulted in assert
failure: m_alignpad == 0 at runtime in 4 CoreMangLib tests.

Commit migrated from https://github.com/dotnet/coreclr/commit/f744448122b6fc3c1868105bcb9e767ed62889d3

src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs

index ded0b7c..8e3759d 100644 (file)
@@ -784,15 +784,26 @@ namespace ILCompiler
                 return;
             }
 
-            if (!_compilationGroup.ContainsTypeLayout(baseType))
+            if (_compilationGroup.ContainsType(baseType))
             {
-                LayoutInt alignment = new LayoutInt(type.Context.Target.PointerSize);
-                if (type.RequiresAlign8())
+                if (_compilationGroup.ContainsTypeLayout(baseType))
                 {
-                    alignment = new LayoutInt(8);
+                    // The type is defined in the module that's currently being compiled and the type layout doesn't depend on other modules
+                    return;
                 }
-                baseOffset = LayoutInt.AlignUp(baseOffset, alignment, type.Context.Target);
             }
+            else if (_compilationGroup.VersionsWithType(baseType))
+            {
+                // The baseType is in the current version bubble, but in a module different from the one that's currently being compiled
+                return;
+            }
+
+            LayoutInt alignment = new LayoutInt(type.Context.Target.PointerSize);
+            if (type.RequiresAlign8())
+            {
+                alignment = new LayoutInt(8);
+            }
+            baseOffset = LayoutInt.AlignUp(baseOffset, alignment, type.Context.Target);
         }
 
         public static bool IsManagedSequentialType(TypeDesc type)