Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFadi Hanna <fadim@microsoft.com>2017-08-16 21:51:27 +0300
committerFadi Hanna <fadim@microsoft.com>2017-08-16 21:51:27 +0300
commit9098fbfe1660fe26539f60439ed3242fbb9aba5a (patch)
tree24cfaced3dc183797b5532df35867ee358e41a3b /src/System.Private.TypeLoader
parent0f701216d41eb039490d9bca21840bc3ee9ae7d3 (diff)
• Fix native layout encoding for USG vtable methods requiring a calling convention converter
• Fix binder/ILCompiler/typeloader to correctly handle vtable entries for dynamic types in the partial canonical case where a call converter thunk is not needed, or where it's needed but need to use the generic context of a base type. • Add new tests to PX dynamic generics • Minor refactoring to genericdictinoarycell.cs to make log easier to read (grouping logging of dictionary cells together) [tfs-changeset: 1670506]
Diffstat (limited to 'src/System.Private.TypeLoader')
-rw-r--r--src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs30
-rw-r--r--src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/genericdictionarycell.cs18
2 files changed, 36 insertions, 12 deletions
diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs
index 1bd8b2035..a1da52d2c 100644
--- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs
+++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs
@@ -998,6 +998,20 @@ namespace Internal.Runtime.TypeLoader
TypeLoaderLogger.WriteLine("Allocated new method dictionary for method " + method.ToString() + " @ " + rmd.LowLevelToString());
}
+ private RuntimeTypeHandle[] GetGenericContextOfBaseType(DefType type, int vtableMethodSlot)
+ {
+ DefType baseType = type.BaseType;
+ Debug.Assert(baseType == null || !GetRuntimeTypeHandle(baseType).IsNull());
+ Debug.Assert(vtableMethodSlot < GetRuntimeTypeHandle(type).GetNumVtableSlots());
+
+ int numBaseTypeVtableSlots = baseType == null ? 0 : GetRuntimeTypeHandle(baseType).GetNumVtableSlots();
+
+ if (vtableMethodSlot < numBaseTypeVtableSlots)
+ return GetGenericContextOfBaseType(baseType, vtableMethodSlot);
+ else
+ return GetRuntimeTypeHandles(type.Instantiation);
+ }
+
private unsafe void FinishVTableCallingConverterThunks(TypeDesc type, TypeBuilderState state)
{
Debug.Assert(state.TemplateType.IsCanonicalSubtype(CanonicalFormKind.Universal));
@@ -1009,9 +1023,11 @@ namespace Internal.Runtime.TypeLoader
IntPtr* vtableCells = (IntPtr*)((byte*)GetRuntimeTypeHandle(type).ToIntPtr() + sizeof(EEType));
Debug.Assert((state.VTableMethodSignatures.Length - state.NumSealedVTableMethodSignatures) <= numVtableSlots);
+ TypeDesc baseType = type.BaseType;
+ int numBaseTypeVtableSlots = GetRuntimeTypeHandle(baseType).GetNumVtableSlots();
+
// Generic context
RuntimeTypeHandle[] typeArgs = Empty<RuntimeTypeHandle>.Array;
- RuntimeTypeHandle[] methodArgs = Empty<RuntimeTypeHandle>.Array; // No GVMs in vtables
if (type is DefType)
typeArgs = GetRuntimeTypeHandles(((DefType)type).Instantiation);
@@ -1020,11 +1036,21 @@ namespace Internal.Runtime.TypeLoader
for (int i = 0; i < state.VTableMethodSignatures.Length; i++)
{
+ RuntimeTypeHandle[] typeArgsToUse = typeArgs;
+
int vtableSlotInDynamicType = -1;
if (!state.VTableMethodSignatures[i].IsSealedVTableSlot)
{
vtableSlotInDynamicType = state.VTableSlotsMapping.GetVTableSlotInTargetType((int)state.VTableMethodSignatures[i].VTableSlot);
Debug.Assert(vtableSlotInDynamicType != -1);
+
+ if (vtableSlotInDynamicType < numBaseTypeVtableSlots)
+ {
+ // Vtable method from the vtable portion of a base type. Use generic context of the basetype defining the vtable slot.
+ // We should never reach here for array types (the vtable entries of the System.Array basetype should never need a converter).
+ Debug.Assert(type is DefType);
+ typeArgsToUse = GetGenericContextOfBaseType((DefType)type, vtableSlotInDynamicType);
+ }
}
IntPtr originalFunctionPointerFromVTable = state.VTableMethodSignatures[i].IsSealedVTableSlot ?
@@ -1036,7 +1062,7 @@ namespace Internal.Runtime.TypeLoader
originalFunctionPointerFromVTable,
state.VTableMethodSignatures[i].MethodSignature,
IntPtr.Zero, // No instantiating arg for non-generic instance methods
- typeArgs,
+ typeArgsToUse,
Empty<RuntimeTypeHandle>.Array); // No GVMs in vtables, no no method args
if (state.VTableMethodSignatures[i].IsSealedVTableSlot)
diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/genericdictionarycell.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/genericdictionarycell.cs
index 05b4daaf3..a07d6dad8 100644
--- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/genericdictionarycell.cs
+++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/genericdictionarycell.cs
@@ -1071,11 +1071,15 @@ namespace Internal.Runtime.TypeLoader
for (uint i = 0; i < count; i++)
{
+ TypeLoaderLogger.WriteLine(" -> DictionaryCell[" + i.LowLevelToString() + "] = ");
+
GenericDictionaryCell cell = ParseAndCreateCell(nativeLayoutInfoLoadContext, ref parser);
- cell.Prepare(typeBuilder);
dictionary[i] = cell;
}
+ for (uint i = 0; i < count; i++)
+ dictionary[i].Prepare(typeBuilder);
+
return dictionary;
}
@@ -1815,15 +1819,7 @@ namespace Internal.Runtime.TypeLoader
NativeParser sigParser = parser.GetParserFromRelativeOffset();
RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature(nativeLayoutInfoLoadContext._module.Handle, sigParser.Offset);
-#if TYPE_LOADER_TRACE
- TypeLoaderLogger.WriteLine("CallingConventionConverter on: ");
- TypeLoaderLogger.WriteLine(" -> Flags: " + ((int)flags).LowLevelToString());
- TypeLoaderLogger.WriteLine(" -> Signature: " + signature.NativeLayoutSignature().LowLevelToString());
- for (int i = 0; !nativeLayoutInfoLoadContext._typeArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._typeArgumentHandles.Length; i++)
- TypeLoaderLogger.WriteLine(" -> TypeArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._typeArgumentHandles[i]);
- for (int i = 0; !nativeLayoutInfoLoadContext._methodArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._methodArgumentHandles.Length; i++)
- TypeLoaderLogger.WriteLine(" -> MethodArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._methodArgumentHandles[i]);
-#endif
+ TypeLoaderLogger.WriteLine("CallingConventionConverter: Flags=" + ((int)flags).LowLevelToString() + " Signature=" + signature.NativeLayoutSignature().LowLevelToString());
cell = new CallingConventionConverterCell
{
@@ -1844,6 +1840,7 @@ namespace Internal.Runtime.TypeLoader
{
OtherDictionarySlot = parser.GetUnsigned()
};
+ TypeLoaderLogger.WriteLine("PointerToOtherSlot: " + ((PointerToOtherDictionarySlotCell)cell).OtherDictionarySlot.LowLevelToString());
break;
case FixupSignatureKind.IntValue:
@@ -1851,6 +1848,7 @@ namespace Internal.Runtime.TypeLoader
{
Value = new IntPtr((int)parser.GetUnsigned())
};
+ TypeLoaderLogger.WriteLine("IntValue: " + ((IntPtrCell)cell).Value.LowLevelToString());
break;
default: