From 852c865dc90df7411cb3ce42c23adacdcdf99a9d Mon Sep 17 00:00:00 2001 From: Yaroslav Yamshchikov Date: Sat, 15 Feb 2020 00:11:01 +0300 Subject: [PATCH] fix infinite recursion in crossgen2 on ARM (#32227) --- .../TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs | 13 +++++++++---- .../Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs | 5 +++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs index b0be4b8..596bca5 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs @@ -425,7 +425,7 @@ namespace Internal.TypeSystem return computedLayout; } - protected virtual void AlignBaseOffsetIfNecessary(MetadataType type, ref LayoutInt baseOffset) + protected virtual void AlignBaseOffsetIfNecessary(MetadataType type, ref LayoutInt baseOffset, bool requiresAlign8) { } @@ -434,8 +434,6 @@ namespace Internal.TypeSystem // For types inheriting from another type, field offsets continue on from where they left off LayoutInt cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type); - AlignBaseOffsetIfNecessary(type, ref cumulativeInstanceFieldPos); - var layoutMetadata = type.GetClassLayout(); int packingSize = ComputePackingSize(type, layoutMetadata); @@ -459,6 +457,7 @@ namespace Internal.TypeSystem continue; TypeDesc fieldType = field.FieldType; + if (IsByValueClass(fieldType)) { instanceValueClassFieldCount++; @@ -495,6 +494,7 @@ namespace Internal.TypeSystem // Reset the counters to be used later as the index to insert into the array instanceGCPointerFieldsCount = 0; instanceValueClassFieldCount = 0; + LayoutInt largestAlignmentRequired = LayoutInt.One; // Iterate over all fields and do the following // - Add instance fields to the appropriate array (while maintaining the enumerated order) @@ -506,6 +506,9 @@ namespace Internal.TypeSystem TypeDesc fieldType = field.FieldType; + var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, packingSize); + largestAlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequired); + if (IsByValueClass(fieldType)) { instanceValueClassFieldsArr[instanceValueClassFieldCount++] = field; @@ -516,12 +519,14 @@ namespace Internal.TypeSystem } else { - var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, packingSize); int log2size = CalculateLog2(fieldSizeAndAlignment.Size.AsInt); instanceNonGCPointerFieldsArr[log2size][instanceNonGCPointerFieldsCount[log2size]++] = field; } } + largestAlignmentRequired = type.Context.Target.GetObjectAlignment(largestAlignmentRequired); + AlignBaseOffsetIfNecessary(type, ref cumulativeInstanceFieldPos, largestAlignmentRequired.AsInt > 4); + // We've finished placing the fields into their appropriate arrays // The next optimization may place non-GC Pointers, so repurpose our // counter to keep track of the next non-GC Pointer that must be placed diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs index b624439..5079e20 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs @@ -810,7 +810,7 @@ namespace ILCompiler /// This method decides whether the type needs aligned base offset in order to have layout resilient to /// base class layout changes. /// - protected override void AlignBaseOffsetIfNecessary(MetadataType type, ref LayoutInt baseOffset) + protected override void AlignBaseOffsetIfNecessary(MetadataType type, ref LayoutInt baseOffset, bool requiresAlign8) { if (type.IsValueType) { @@ -837,7 +837,8 @@ namespace ILCompiler } LayoutInt alignment = new LayoutInt(type.Context.Target.PointerSize); - if (type.RequiresAlign8()) + + if (requiresAlign8) { alignment = new LayoutInt(8); } -- 2.7.4