diff options
author | Fadi Hanna <fadim@microsoft.com> | 2017-01-13 21:48:15 +0300 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2017-01-13 21:48:15 +0300 |
commit | 85dde75bf18711139278b6eeae7641ba1ea001a9 (patch) | |
tree | 022a410c2c36458d8ac9cec1637c6a132a596745 | |
parent | f1b398d4ffe2d6ad0f8095b8005bf45540cd64cd (diff) |
Changing the way external native layout offsets get used, to include a CoreRT optimization, avoiding an unnecessary indirection through the ExternalReferences table.
We can optimize in CoreRT because all tables using data from the native layout blob are created by the same entity that creates the native layout blob (unlike in ProjectN, where one could be in NUTC and the native layout is always in the binder, therefore needing the ExternalReferencesTable lookup helper).
[tfs-changeset: 1644455]
5 files changed, 34 insertions, 21 deletions
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index 3d2fe2832..35e6a3e64 100644 --- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -1075,7 +1075,7 @@ namespace Internal.Reflection.Execution } else { - uint nameAndSigOffset = externalReferences.GetNativeLayoutOffsetFromIndex(entryMethodHandleOrNameAndSigRaw); + uint nameAndSigOffset = externalReferences.GetExternalNativeLayoutOffset(entryMethodHandleOrNameAndSigRaw); MethodNameAndSignature nameAndSig; if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(mappingTableModule, nameAndSigOffset, out nameAndSig)) { diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ExternalReferencesTable.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ExternalReferencesTable.cs index 644eac90e..99f151906 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ExternalReferencesTable.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ExternalReferencesTable.cs @@ -137,16 +137,29 @@ namespace Internal.Runtime.TypeLoader { return RuntimeAugments.CreateRuntimeTypeHandle(GetIntPtrFromIndex(index)); } + } - unsafe public uint GetNativeLayoutOffsetFromIndex(uint index) + public static class ExternalReferencesTableExtentions + { + public static uint GetExternalNativeLayoutOffset(this ExternalReferencesTable extRefs, uint index) { - if (index >= _elementsCount) - throw new BadImageFormatException(); - + // CoreRT is a bit more optimized than ProjectN. In ProjectN, some tables that reference data + // in the native layout are constructed at NUTC compilation time, but the native layout is only + // generated at binder time, so we use the external references table to link the nutc-built + // tables with their native layout dependencies. + // + // In ProjectN, the nutc-built tables will be emitted with indices into the external references + // table, and the entries in the external references table will contain the offsets into the + // native layout blob. + // + // In CoreRT, since all tables and native layout blob are built together at the same time, we can + // optimize by writing the native layout offsets directly into the table, without requiring the extra + // lookup in the external references table. + // #if CORERT - return *(uint*)(((IntPtr*)_elements)[index]); + return index; #else - return ((TableElement*)_elements)[index]; + return extRefs.GetRvaFromIndex(index); #endif } } diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TemplateLocator.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TemplateLocator.cs index ec5656cdc..7726b09d6 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TemplateLocator.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TemplateLocator.cs @@ -92,7 +92,7 @@ namespace Internal.Runtime.TypeLoader if (typeDesc == canonForm) { TypeLoaderLogger.WriteLine("Found metadata template for type " + concreteType.ToString() + ": " + typeDesc.ToString()); - nativeLayoutInfoToken = (uint)externalFixupsTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + nativeLayoutInfoToken = (uint)externalFixupsTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { throw new BadImageFormatException(); @@ -150,7 +150,7 @@ namespace Internal.Runtime.TypeLoader if (methodDesc == canonForm) { TypeLoaderLogger.WriteLine("Found metadata template for method " + concreteMethod.ToString() + ": " + methodDesc.ToString()); - nativeLayoutInfoToken = (uint)externalFixupsTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + nativeLayoutInfoToken = (uint)externalFixupsTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { throw new BadImageFormatException(); @@ -197,7 +197,7 @@ namespace Internal.Runtime.TypeLoader if (canonForm == candidateTemplate.ConvertToCanonForm(kind)) { TypeLoaderLogger.WriteLine("Found template for type " + concreteType.ToString() + ": " + candidateTemplate.ToString()); - nativeLayoutInfoToken = (uint)externalFixupsTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + nativeLayoutInfoToken = (uint)externalFixupsTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { // TODO: once multifile gets fixed up, make this throw a BadImageFormatException @@ -269,7 +269,7 @@ namespace Internal.Runtime.TypeLoader NativeParser entryParser; while (!(entryParser = enumerator.GetNext()).IsNull) { - var methodSignatureParser = new NativeParser(nativeLayoutReader, externalFixupsTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned())); + var methodSignatureParser = new NativeParser(nativeLayoutReader, externalFixupsTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned())); // Get the unified generic method holder and convert it to its canonical form var candidateTemplate = (InstantiatedMethod)context.GetMethod(ref methodSignatureParser); @@ -279,7 +279,7 @@ namespace Internal.Runtime.TypeLoader { TypeLoaderLogger.WriteLine("Found template for generic method " + concreteMethod.ToString() + ": " + candidateTemplate.ToString()); nativeLayoutInfoModule = moduleHandle; - nativeLayoutInfoToken = (uint)externalFixupsTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + nativeLayoutInfoToken = (uint)externalFixupsTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { // TODO: once multifile gets fixed up, make this throw a BadImageFormatException diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs index c701c13a6..dd7403ba5 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs @@ -85,7 +85,7 @@ namespace Internal.Runtime.TypeLoader for (uint j = 0; j < numTargetImplementations; j++) { - uint nameAndSigToken = extRefs.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigToken = extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, moduleHandle, nameAndSigToken); RuntimeTypeHandle targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); @@ -114,7 +114,7 @@ namespace Internal.Runtime.TypeLoader { RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle); - NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned())); + NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned())); if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref ifaceSigParser, moduleHandle, targetTypeInstantiation, null, out currentIfaceTypeHandle)) { @@ -226,7 +226,7 @@ namespace Internal.Runtime.TypeLoader if (!openCallingTypeHandle.Equals(interfaceTypeHandle)) continue; - uint nameAndSigToken = extRefs.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigToken = extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature interfaceMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, moduleHandle, nameAndSigToken); if (!interfaceMethodNameAndSignature.Equals(methodNameAndSignature)) @@ -459,13 +459,13 @@ namespace Internal.Runtime.TypeLoader if (!parsedTargetTypeHandle.Equals(openTargetTypeHandle)) continue; - uint parsedCallingNameAndSigToken = extRefs.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint parsedCallingNameAndSigToken = extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature parsedCallingNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, moduleHandle, parsedCallingNameAndSigToken); if (!parsedCallingNameAndSignature.Equals(callingMethodNameAndSignature)) continue; - uint parsedTargetMethodNameAndSigToken = extRefs.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint parsedTargetMethodNameAndSigToken = extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, moduleHandle, parsedTargetMethodNameAndSigToken); Debug.Assert(targetMethodNameAndSignature != null); diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs index c52479aad..22d2c7d56 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs @@ -852,7 +852,7 @@ namespace Internal.Runtime.TypeLoader if (!entryType.Equals(definitionType)) continue; - uint nameAndSigPointerToken = externalReferences.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigPointerToken = externalReferences.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature nameAndSig; if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, nameAndSigPointerToken, out nameAndSig)) @@ -995,7 +995,7 @@ namespace Internal.Runtime.TypeLoader if (!entryType.Equals(definitionType)) continue; - uint nameAndSigPointerToken = externalReferences.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigPointerToken = externalReferences.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); uint parentHierarchyAndFlag = entryParser.GetUnsigned(); bool isGenericVirtualMethod = ((parentHierarchyAndFlag & VirtualInvokeTableEntry.FlagsMask) == VirtualInvokeTableEntry.GenericVirtualMethod); @@ -1576,7 +1576,7 @@ namespace Internal.Runtime.TypeLoader } else { - uint nameAndSigToken = extRefTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigToken = extRefTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); MethodNameAndSignature nameAndSig; if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigToken, out nameAndSig)) { @@ -1608,7 +1608,7 @@ namespace Internal.Runtime.TypeLoader { Debug.Assert((_hasEntryPoint || ((_flags & InvokeTableFlags.HasVirtualInvoke) != 0)) && ((_flags & InvokeTableFlags.RequiresInstArg) != 0)); - uint nameAndSigPointerToken = extRefTable.GetNativeLayoutOffsetFromIndex(entryParser.GetUnsigned()); + uint nameAndSigPointerToken = extRefTable.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()); if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigPointerToken, out _nameAndSignature)) { Debug.Assert(false); //Error |