Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1105,13 +1105,23 @@ public static RuntimeTypeHandle CreateEEType(TypeDesc type, TypeBuilderState sta
return state.HalfBakedRuntimeTypeHandle;
}

public static IntPtr GetDictionary(EEType* pEEType)
public static int GetDictionaryOffsetInEEtype(EEType* pEEType)
{
// Dictionary slot is the first vtable slot

EEType* pBaseType = pEEType->BaseType;
int dictionarySlot = (pBaseType == null ? 0 : pBaseType->NumVtableSlots);
return *(IntPtr*)((byte*)pEEType + sizeof(EEType) + dictionarySlot * IntPtr.Size);
return sizeof(EEType) + dictionarySlot * IntPtr.Size;
}

public static IntPtr GetDictionaryAtOffset(EEType* pEEType, int offset)
{
return *(IntPtr*)((byte*)pEEType + offset);
}

public static IntPtr GetDictionary(EEType* pEEType)
{
return GetDictionaryAtOffset(pEEType, GetDictionaryOffsetInEEtype(pEEType));
}

public static int GetDictionarySlotInVTable(TypeDesc type)
Expand Down Expand Up @@ -1140,5 +1150,24 @@ private static int GetMostDerivedDictionarySlot(ref TypeDesc nextTypeToExamineFo
typeWithDictionary = null;
return -1;
}

public static EEType* GetBaseEETypeForDictionaryPtr(EEType* pEEType, IntPtr dictionaryPtr)
{
// Look for the exact base type that owns the dictionary
IntPtr curDictPtr = GetDictionary(pEEType);
EEType* pBaseEEType = pEEType;

while (curDictPtr != dictionaryPtr)
{
pBaseEEType = pBaseEEType->BaseType;
Debug.Assert(pBaseEEType != null);
// Since in multifile scenario, the base type's dictionary may end up having
// a copy in each module, therefore the lookup of the right base type should be
// based on the dictionary pointer in the current EEtype, instead of the base EEtype.
curDictPtr = GetDictionaryAtOffset(pEEType, EETypeCreator.GetDictionaryOffsetInEEtype(pBaseEEType));
}

return pBaseEEType;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -526,21 +526,11 @@ public unsafe IntPtr UpdateFloatingDictionary(IntPtr context, IntPtr dictionaryP

if (isTypeContext)
{
EEType* pEEType = (EEType*)context.ToPointer();
IntPtr curDictPtr = EETypeCreator.GetDictionary(pEEType);

// Look for the exact base type that owns the dictionary. We may be having
// a virtual method run on a derived type and the generic lookup are performed
// on the base type's dictionary.
while (curDictPtr != dictionaryPtr)
{
pEEType = pEEType->BaseType;
Debug.Assert(pEEType != null);
curDictPtr = EETypeCreator.GetDictionary(pEEType);
Debug.Assert(curDictPtr != IntPtr.Zero);
}

context = (IntPtr)pEEType;
EEType* pEEType = (EEType*)context.ToPointer();
context = (IntPtr)EETypeCreator.GetBaseEETypeForDictionaryPtr(pEEType, dictionaryPtr);
}

using (LockHolder.Hold(_typeLoaderLock))
Expand Down