Skip to content

Commit

Permalink
Fix OffsetBias for object; improve handling of indeterminate types
Browse files Browse the repository at this point in the history
  • Loading branch information
trylek committed Apr 5, 2021
1 parent db2146e commit 2c9bbd4
Showing 1 changed file with 12 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,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 + offsetBias);
offsets[fieldOrdinal] = new FieldAndOffset(instanceValueClassFieldsArr[i], cumulativeInstanceFieldPos.IsIndeterminate ? cumulativeInstanceFieldPos : cumulativeInstanceFieldPos + offsetBias);

// 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 @@ -701,7 +701,9 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
}

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

ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
Expand All @@ -719,7 +721,7 @@ private static void PlaceInstanceField(FieldDesc field, int packingSize, FieldAn
var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize, out bool _);

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

fieldOrdinal++;
Expand Down Expand Up @@ -760,27 +762,28 @@ public LayoutInt CalculateFieldBaseOffset(MetadataType type, bool requiresAlign8
{
LayoutInt cumulativeInstanceFieldPos = LayoutInt.Zero;

if (!type.IsValueType)
if (!type.IsValueType && type.HasBaseType)
{
LayoutInt offsetBias = OffsetBias(type);
if (type.HasBaseType)
cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned;
if (!type.BaseType.InstanceByteCountUnaligned.IsIndeterminate)
{
LayoutInt offsetBias = OffsetBias(type);
cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned - offsetBias;
if (!type.BaseType.IsObject && type.BaseType.IsZeroSizedReferenceType)
if (type.BaseType.IsZeroSizedReferenceType && ((MetadataType)type.BaseType).IsExplicitLayout)
{
cumulativeInstanceFieldPos += LayoutInt.One;
}
AlignBaseOffsetIfNecessary(type, ref cumulativeInstanceFieldPos, requiresAlign8);
cumulativeInstanceFieldPos += offsetBias;
}
cumulativeInstanceFieldPos += offsetBias;
}

return cumulativeInstanceFieldPos;
}

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

private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType, int packingSize, out bool layoutAbiStable)
Expand Down

0 comments on commit 2c9bbd4

Please sign in to comment.