Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
filipnavara committed Aug 4, 2024
1 parent dee8a8b commit 0ccb0d4
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@ internal bool RequiresAlign8
{
get
{
if ((ExtendedFlags & (ushort)EETypeFlagsEx.RequiresAlign8Flag) != 0)
return true;
return (RareFlags & EETypeRareFlags.RequiresAlign8Flag) != 0;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,7 @@ private static unsafe object AllocateThreadStaticStorageForType(TypeManagerHandl
gcDesc = Internal.Runtime.Augments.RuntimeAugments.TypeLoaderCallbacks.GetThreadStaticGCDescForDynamicType(typeManager, typeTlsIndex);
}

MethodTable *pMethodTable = (MethodTable*)gcDesc;
#if FEATURE_64BIT_ALIGNMENT
if (pMethodTable->RequiresAlign8)
{
return InternalCalls.RhpNewFastAlign8(pMethodTable);
}
#endif

return RuntimeImports.RhNewObject(pMethodTable);
return RuntimeImports.RhNewObject((MethodTable*)gcDesc);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ mdType.Name is "WeakReference" or "WeakReference`1" &&
flagsEx |= (ushort)EETypeFlagsEx.IDynamicInterfaceCastableFlag;
}

if (type.RequiresAlign8())
{
flagsEx |= (ushort)EETypeFlagsEx.RequiresAlign8Flag;
}

return flagsEx;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ internal enum EETypeFlagsEx : ushort
/// This type implements IDynamicInterfaceCastable to allow dynamic resolution of interface casts.
/// </summary>
IDynamicInterfaceCastableFlag = 0x0008,

RequiresAlign8Flag = 0x1000,
}

internal enum EETypeKind : uint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public static GCPointerMap FromStaticLayout(MetadataType type)
builder.GetInnerBuilder(field.Offset.AsInt, fieldDefType.InstanceByteCount.AsInt);
FromInstanceLayoutHelper(ref innerBuilder, fieldDefType);
}
if (fieldDefType.RequiresAlign8())
{
builder.RequiresAlign8();
}
}
}

Expand Down Expand Up @@ -122,6 +126,10 @@ private static void MapThreadStaticsForType(ref GCPointerMapBuilder builder, Met
builder.GetInnerBuilder(field.Offset.AsInt + baseOffset, fieldDefType.InstanceByteCount.AsInt);
FromInstanceLayoutHelper(ref innerBuilder, fieldDefType);
}
if (fieldDefType.RequiresAlign8())
{
builder.RequiresAlign8();
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public partial struct GCPointerMap : IEquatable<GCPointerMap>, IComparable<GCPoi

private int _numCells;

private bool _requiresAlign8;

/// <summary>
/// Gets a value indicating whether this map is initialized.
/// </summary>
Expand Down Expand Up @@ -77,6 +79,8 @@ public bool IsAllGCPointers
}
}

public bool RequiresAlign8 => _requiresAlign8;

public bool this[int index]
{
get
Expand All @@ -85,11 +89,12 @@ public bool this[int index]
}
}

public GCPointerMap(uint[] gcFlags, int numCells)
public GCPointerMap(uint[] gcFlags, int numCells, bool requiresAlign8)
{
Debug.Assert(numCells <= gcFlags.Length << 5);
_gcFlags = gcFlags;
_numCells = numCells;
_requiresAlign8 = requiresAlign8;
}

public BitEnumerator GetEnumerator()
Expand All @@ -111,6 +116,9 @@ public bool Equals(GCPointerMap other)
if (_gcFlags[i] != other._gcFlags[i])
return false;

if (_requiresAlign8 != other.RequiresAlign8)
return false;

return true;
}

Expand Down Expand Up @@ -141,6 +149,9 @@ public int CompareTo(GCPointerMap other)
return (int)(_gcFlags[i] - other._gcFlags[i]);
}

if (_requiresAlign8 != other.RequiresAlign8)
return _requiresAlign8 ? 1 : -1;

Debug.Assert(Equals(other));
return 0;
}
Expand All @@ -161,6 +172,8 @@ public struct GCPointerMapBuilder
private int _delta;
private int _limit;

private bool _requiresAlign8;

public GCPointerMapBuilder(int numBytes, int pointerSize)
{
// Align the size up. The size of the pointer map is used to infer the statics storage size that has
Expand All @@ -183,6 +196,7 @@ public GCPointerMapBuilder(int numBytes, int pointerSize)

_delta = 0;
_limit = numBytes;
_requiresAlign8 = false;
}

public void MarkGCPointer(int offset)
Expand All @@ -199,6 +213,11 @@ public void MarkGCPointer(int offset)
_gcFlags[cellIndex >> 5] |= 1u << (cellIndex & 0x1F);
}

public void RequiresAlign8()
{
_requiresAlign8 = true;
}

public GCPointerMapBuilder GetInnerBuilder(int offset, int size)
{
Debug.Assert(offset >= 0);
Expand All @@ -219,7 +238,7 @@ public GCPointerMapBuilder GetInnerBuilder(int offset, int size)
public GCPointerMap ToGCMap()
{
Debug.Assert(_delta == 0);
return new GCPointerMap(_gcFlags, (_limit + _pointerSize - 1) / _pointerSize);
return new GCPointerMap(_gcFlags, (_limit + _pointerSize - 1) / _pointerSize, _requiresAlign8);
}

public BitEnumerator GetEnumerator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,8 @@ private void ComputeRareFlags(NodeFactory factory)
flags |= (uint)EETypeRareFlags.HasCctorFlag;
}

if (_type.RequiresAlign8())
// Types without component size use EETypeFlagsEx to store the RequiresAlign8 flag
if (!_type.IsArray && !_type.IsString && _type.RequiresAlign8())
{
flags |= (uint)EETypeRareFlags.RequiresAlign8Flag;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ int ISymbolDefinitionNode.Offset

public override bool IsShareable => true;

public bool RequiresAlign8 => _gcMap.RequiresAlign8;

protected override ObjectData GetDehydratableData(NodeFactory factory, bool relocsOnly = false)
{
ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory, relocsOnly);
Expand All @@ -83,6 +85,13 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
if (containsPointers)
flags |= (uint)EETypeFlags.HasPointersFlag;

if (_gcMap.RequiresAlign8)
{
// Mark the method table as non-value type that requires 8-byte alignment
flags |= (uint)EETypeFlagsEx.RequiresAlign8Flag;
flags |= (uint)EETypeElementType.Class << (byte)EETypeFlags.ElementTypeShift;
}

dataBuilder.EmitUInt(flags);

totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC MethodTable size is 3 pointers
Expand Down

0 comments on commit 0ccb0d4

Please sign in to comment.