diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs index 4c7c5cfb6c599f..59d20f1eac91be 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs @@ -412,6 +412,8 @@ protected static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(Metada cumulativeInstanceFieldPos = LayoutInt.Max(cumulativeInstanceFieldPos, new LayoutInt(layoutMetadata.Size)); } + largestAlignmentRequirement = FixDecimalOnARM32Alignment(type, largestAlignmentRequirement); + SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment); @@ -425,6 +427,38 @@ protected static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(Metada return computedLayout; } + //From InteropTypes.cs + protected static bool IsSystemDecimal(TypeSystemContext context, TypeDesc type) + { + bool IsCoreNamedType(TypeSystemContext context, TypeDesc type, string @namespace, string name) + { + return type is MetadataType mdType && + mdType.Name == name && + mdType.Namespace == @namespace && + mdType.Module == context.SystemModule; + } + + return IsCoreNamedType(context, type, "System", "Decimal"); + } + + protected static LayoutInt FixDecimalOnARM32Alignment(MetadataType type, LayoutInt alignment) + { + /* ./vm/methodtablebuilder.cpp + // This is required because native layout of System.Decimal causes it to be aligned + // differently to the layout of the native DECIMAL structure, which will cause + // data misalignent exceptions if Decimal is embedded in another type. + + if (strcmp(name, g_DecimalName) == 0) { + pLayout->m_ManagedLargestAlignmentRequirementOfAllMembers = sizeof(ULONGLONG); + */ + if (type.IsValueType && type.Context.Target.Architecture == TargetArchitecture.ARM && IsSystemDecimal(type.Context, type)) + { + return new LayoutInt(8); + } + return alignment; + } + + protected virtual void AlignBaseOffsetIfNecessary(MetadataType type, ref LayoutInt baseOffset, bool requiresAlign8) { }