Skip to content

Commit

Permalink
More consistency fixes for x86 and arm
Browse files Browse the repository at this point in the history
  • Loading branch information
trylek committed Apr 5, 2021
1 parent 8db3511 commit 943cd4d
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,11 @@ protected static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(Metadata
{
// Instance slice size is the total size of instance not including the base type.
// It is calculated as the field whose offset and size add to the greatest value.
LayoutInt offsetBias = !type.IsValueType ? new LayoutInt(type.Context.Target.PointerSize) : LayoutInt.Zero;
LayoutInt cumulativeInstanceFieldPos =
type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : LayoutInt.Zero;
LayoutInt instanceSize = cumulativeInstanceFieldPos;
cumulativeInstanceFieldPos -= offsetBias;

var layoutMetadata = type.GetClassLayout();

Expand All @@ -333,7 +335,7 @@ protected static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(Metadata
if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type);

LayoutInt computedOffset = fieldAndOffset.Offset + cumulativeInstanceFieldPos;
LayoutInt computedOffset = fieldAndOffset.Offset + cumulativeInstanceFieldPos + offsetBias;

// GC pointers MUST be aligned.
// We treat byref-like structs as GC pointers too.
Expand Down Expand Up @@ -388,11 +390,10 @@ protected ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType
{
var offsets = new FieldAndOffset[numInstanceFields];

LayoutInt offsetBias = OffsetBias(type);

// For types inheriting from another type, field offsets continue on from where they left off
// For reference types, we calculate field alignment as if the address after the method table pointer
// has offset 0 (on 32-bit platforms, this location is guaranteed to be 8-aligned).
LayoutInt offsetBias = !type.IsValueType ? new LayoutInt(type.Context.Target.PointerSize) : LayoutInt.Zero;
LayoutInt cumulativeInstanceFieldPos = CalculateFieldBaseOffset(type, requiresAlign8: false, requiresAlignedBase: false) - offsetBias;

var layoutMetadata = type.GetClassLayout();
Expand Down Expand Up @@ -538,16 +539,10 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
largestAlignmentRequired = context.Target.GetObjectAlignment(largestAlignmentRequired);
bool requiresAlign8 = !largestAlignmentRequired.IsIndeterminate && largestAlignmentRequired.AsInt > 4;

LayoutInt offsetBias = OffsetBias(type);

// For types inheriting from another type, field offsets continue on from where they left off
// Base alignment is not always required, it's only applied when there's a version bubble boundary
// between base type and the current type.
LayoutInt cumulativeInstanceFieldPos = CalculateFieldBaseOffset(type, requiresAlign8, requiresAlignedBase: false);
if (!cumulativeInstanceFieldPos.IsIndeterminate)
{
cumulativeInstanceFieldPos -= offsetBias;
}

// We've finished placing the fields into their appropriate arrays
// The next optimization may place non-GC Pointers, so repurpose our
Expand Down Expand Up @@ -621,7 +616,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
// Place the field
j = instanceNonGCPointerFieldsCount[i];
FieldDesc field = instanceNonGCPointerFieldsArr[i][j];
PlaceInstanceField(field, packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal, offsetBias);
PlaceInstanceField(field, packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal);

instanceNonGCPointerFieldsCount[i]++;
}
Expand All @@ -638,14 +633,14 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
{
for (int j = 0; j < instanceGCPointerFieldsArr.Length; j++)
{
PlaceInstanceField(instanceGCPointerFieldsArr[j], packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal, offsetBias);
PlaceInstanceField(instanceGCPointerFieldsArr[j], packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal);
}
}

// The start index will be the index that may have been increased in the previous optimization
for (int j = instanceNonGCPointerFieldsCount[i]; j < instanceNonGCPointerFieldsArr[i].Length; j++)
{
PlaceInstanceField(instanceNonGCPointerFieldsArr[i][j], packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal, offsetBias);
PlaceInstanceField(instanceNonGCPointerFieldsArr[i][j], packingSize, offsets, ref cumulativeInstanceFieldPos, ref fieldOrdinal);
}
}

Expand All @@ -668,7 +663,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
LayoutInt AlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, context.Target.LayoutPointerSize);
cumulativeInstanceFieldPos = AlignUpInstanceFieldOffset(type, cumulativeInstanceFieldPos, AlignmentRequired, context.Target);
}
offsets[fieldOrdinal] = new FieldAndOffset(instanceValueClassFieldsArr[i], cumulativeInstanceFieldPos.IsIndeterminate ? cumulativeInstanceFieldPos : cumulativeInstanceFieldPos + offsetBias);
offsets[fieldOrdinal] = new FieldAndOffset(instanceValueClassFieldsArr[i], cumulativeInstanceFieldPos);

// If the field has an indeterminate size, align the cumulative field offset to the indeterminate value
// Otherwise, align the cumulative field offset to the aligned-instance field size
Expand Down Expand Up @@ -703,9 +698,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
}

SizeAndAlignment instanceByteSizeAndAlignment;
var instanceSizeAndAlignment = ComputeInstanceSize(type,
cumulativeInstanceFieldPos.IsIndeterminate ? cumulativeInstanceFieldPos : cumulativeInstanceFieldPos + offsetBias,
minAlign, 0/* specified field size unused */, out instanceByteSizeAndAlignment);
var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, minAlign, 0/* specified field size unused */, out instanceByteSizeAndAlignment);

ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
Expand All @@ -718,12 +711,12 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
return computedLayout;
}

private static void PlaceInstanceField(FieldDesc field, int packingSize, FieldAndOffset[] offsets, ref LayoutInt instanceFieldPos, ref int fieldOrdinal, LayoutInt offsetBias)
private static void PlaceInstanceField(FieldDesc field, int packingSize, FieldAndOffset[] offsets, ref LayoutInt instanceFieldPos, ref int fieldOrdinal)
{
var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize, out bool _);

instanceFieldPos = AlignUpInstanceFieldOffset(field.OwningType, instanceFieldPos, fieldSizeAndAlignment.Alignment, field.Context.Target);
offsets[fieldOrdinal] = new FieldAndOffset(field, instanceFieldPos.IsIndeterminate ? instanceFieldPos : instanceFieldPos + offsetBias);
offsets[fieldOrdinal] = new FieldAndOffset(field, instanceFieldPos);
instanceFieldPos = checked(instanceFieldPos + fieldSizeAndAlignment.Size);

fieldOrdinal++;
Expand Down Expand Up @@ -769,25 +762,18 @@ public LayoutInt CalculateFieldBaseOffset(MetadataType type, bool requiresAlign8
cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned;
if (!type.BaseType.InstanceByteCountUnaligned.IsIndeterminate)
{
LayoutInt offsetBias = OffsetBias(type);
cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned - offsetBias;
if (type.BaseType.IsZeroSizedReferenceType && ((MetadataType)type.BaseType).IsExplicitLayout)
cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned;
if (type.BaseType.IsZeroSizedReferenceType && ((MetadataType)type.BaseType).HasLayout())
{
cumulativeInstanceFieldPos += LayoutInt.One;
}
AlignBaseOffsetIfNecessary(type, ref cumulativeInstanceFieldPos, requiresAlign8, requiresAlignedBase);
cumulativeInstanceFieldPos += offsetBias;
}
}

return cumulativeInstanceFieldPos;
}

public static LayoutInt OffsetBias(TypeDesc type)
{
return !type.IsValueType && type.HasBaseType ? new LayoutInt(type.Context.Target.PointerSize) : LayoutInt.Zero;
}

private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType, int packingSize, out bool layoutAbiStable)
{
SizeAndAlignment result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ public bool EnforceOwningType(EcmaModule module)
/// </summary>
public abstract bool IsInputBubble { get; }

/// <summary>
/// Returns true when the base type and derived type don't reside in the same version bubble
/// in which case the runtime aligns the field base offset.
/// </summary>
public abstract bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType);

/// <summary>
/// List of input modules to use for the compilation.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
&& !_fieldDesc.IsStatic
&& !_fieldDesc.OwningType.IsValueType)
{
baseOffset = (uint)((MetadataType)_fieldDesc.OwningType).FieldBaseOffset().AsInt;
if (!factory.CompilationModuleGroup.VersionsWithType(_fieldDesc.OwningType.BaseType))
MetadataType owningType = (MetadataType)_fieldDesc.OwningType;
baseOffset = (uint)owningType.FieldBaseOffset().AsInt;
if (factory.CompilationModuleGroup.NeedsAlignmentBetweenBaseTypeAndDerived((MetadataType)baseType, owningType))
{
fieldOffset -= baseOffset;
baseOffset = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,11 @@ private bool ModuleMatchesCompilationUnitIndex(ModuleDesc module1, ModuleDesc mo
return ModuleToCompilationUnitIndex(module1) == ModuleToCompilationUnitIndex(module2);
}

public bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType)
public override bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType)
{
if (baseType.IsObject)
return false;

if (!ModuleMatchesCompilationUnitIndex(derivedType.Module, baseType.Module) ||
TypeLayoutCompilationUnits(baseType).HasMultipleCompilationUnits)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ protected override void AlignBaseOffsetIfNecessary(MetadataType type, ref Layout
{
if (requiresAlignedBase || _compilationGroup.NeedsAlignmentBetweenBaseTypeAndDerived(baseType: (MetadataType)type.BaseType, derivedType: type))
{
LayoutInt alignment = new LayoutInt(requiresAlign8 ? 8 : type.Context.Target.PointerSize);
LayoutInt alignment = new LayoutInt(requiresAlign8 || type.BaseType.RequiresAlign8() ? 8 : type.Context.Target.PointerSize);
baseOffset = LayoutInt.AlignUp(baseOffset, alignment, type.Context.Target);
}
}
Expand Down

0 comments on commit 943cd4d

Please sign in to comment.