Skip to content

Commit

Permalink
Add support for gc statics of dynamic types (dotnet#5011)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonerdo committed Oct 18, 2020
1 parent 9136c6c commit 47e98a7
Showing 1 changed file with 50 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,16 @@ private static void CreateEETypeWorker(EEType* pTemplateEEType, UInt32 hashCodeO
// create GC desc
if (state.GcDataSize != 0 && state.GcStaticDesc == IntPtr.Zero)
{
if (state.GcStaticEEType == IntPtr.Zero)
{
int cbStaticGCDesc;
state.GcStaticDesc = CreateStaticGCDesc(state.StaticGCLayout, out state.AllocatedStaticGCDesc, out cbStaticGCDesc);
state.GcStaticEEType = (IntPtr)CreateGcStaticEEType(state, hashCodeOfNewType);
#if GENERICS_FORCE_USG
TestGCDescsForEquality(state.GcStaticDesc, state.NonUniversalStaticGCDesc, cbStaticGCDesc, false);
#endif
}

if (state.GcStaticEEType != IntPtr.Zero)
{
// CoreRT Abi uses managed heap-allocated GC statics
Expand All @@ -642,14 +652,6 @@ private static void CreateEETypeWorker(EEType* pTemplateEEType, UInt32 hashCodeO
*((IntPtr*)gcStaticsIndirection) = gcStaticData;
pEEType->DynamicGcStaticsData = gcStaticsIndirection;
}
else
{
int cbStaticGCDesc;
state.GcStaticDesc = CreateStaticGCDesc(state.StaticGCLayout, out state.AllocatedStaticGCDesc, out cbStaticGCDesc);
#if GENERICS_FORCE_USG
TestGCDescsForEquality(state.GcStaticDesc, state.NonUniversalStaticGCDesc, cbStaticGCDesc, false);
#endif
}
}

if (state.ThreadDataSize != 0 && state.ThreadStaticDesc == IntPtr.Zero)
Expand Down Expand Up @@ -724,6 +726,46 @@ private static void CreateEETypeWorker(EEType* pTemplateEEType, UInt32 hashCodeO
}
}

private static EEType* CreateGcStaticEEType(TypeBuilderState state, UInt32 hashCodeOfNewType)
{
Debug.Assert(state.AllocatedStaticGCDesc);
int cbEEType = (int)EEType.GetSizeofEEType(
cVirtuals: 0,
cInterfaces: 0,
fHasFinalizer: false,
fRequiresOptionalFields: false,
fHasSealedVirtuals: false,
fHasGenericInfo: false,
fHasNonGcStatics: false,
fHasGcStatics: false,
fHasThreadStatics: false);

int baseSize = IntPtr.Size; // sync block

int* gcStaticDesc = (int*)state.GcStaticDesc;
int numSeries = *gcStaticDesc;

for (int i = 0; i < numSeries; i++)
{
int size = *(gcStaticDesc + 1);
int offset = *(gcStaticDesc + 2);

baseSize += size;
gcStaticDesc = gcStaticDesc + 3;
}

EEType* gcEEType = (EEType*)MemoryHelpers.AllocateMemory(cbEEType);
gcEEType->BaseSize = (uint)baseSize;
gcEEType->Flags = (ushort)EETypeFlags.IsDynamicTypeFlag | (ushort)EETypeKind.CanonicalEEType;
gcEEType->ComponentSize = 0;
gcEEType->NumVtableSlots = 0;
gcEEType->NumInterfaces = 0;
gcEEType->HashCode = hashCodeOfNewType;
gcEEType->BaseType = TypeSystemContextFactory.Create().GetWellKnownType(WellKnownType.Object).RuntimeTypeHandle.ToEETypePtr();

return gcEEType;
}

private static IntPtr CreateStaticGCDesc(LowLevelList<bool> gcBitfield, out bool allocated, out int cbGCDesc)
{
if (gcBitfield != null)
Expand Down

0 comments on commit 47e98a7

Please sign in to comment.