From 9c0d9cd9cb0d38978bfffd3c8c43f0156cc7f3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 31 Mar 2023 17:06:14 +0900 Subject: [PATCH] Split `TryGetGenericMethodComponents` into two overloads (#84156) Resolves #83069. Hello World is now 1.45 MB, down from 1.65 MB. Half of the callers don't care about the `MethodNameAndSignature` part - don't spend time computing it. This also allows trimming `MethodNameAndSignature` from a hello world, which allows trimming pretty much all of the type loader. --- ...EnvironmentImplementation.MappingTables.cs | 3 +- .../Runtime/TypeLoader/TypeBuilder.cs | 3 +- ...ronment.ConstructedGenericMethodsLookup.cs | 30 +++++++++++++------ .../TypeLoaderEnvironment.Metadata.cs | 21 ++----------- .../TypeLoaderEnvironment.SignatureParsing.cs | 10 ++----- .../SmokeTests/HardwareIntrinsics/Program.cs | 12 +++++--- 6 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index 45446ed7d8a73..bcdd3bc674eb5 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -890,8 +890,7 @@ private unsafe bool TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(NativeFor { if ((entryFlags & InvokeTableFlags.RequiresInstArg) != 0) { - MethodNameAndSignature dummyNameAndSignature; - bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out dummyNameAndSignature, out genericMethodTypeArgumentHandles); + bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out genericMethodTypeArgumentHandles); Debug.Assert(success); } else diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 0668dc4d88057..f6674fb35624e 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -1101,9 +1101,8 @@ private unsafe IntPtr BuildGenericLookupTarget(TypeSystemContext typeSystemConte if ((contextKind & GenericContextKind.FromMethodHiddenArg) != 0) { RuntimeTypeHandle declaringTypeHandle; - MethodNameAndSignature nameAndSignature; RuntimeTypeHandle[] genericMethodArgHandles; - bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(context, out declaringTypeHandle, out nameAndSignature, out genericMethodArgHandles); + bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(context, out declaringTypeHandle, out genericMethodArgHandles); Debug.Assert(success); if (RuntimeAugments.IsGenericType(declaringTypeHandle)) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs index af00913b58af9..fb97c972b5851 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs @@ -148,9 +148,7 @@ internal override bool MatchParsedEntry(ref NativeParser entryParser, ref Extern RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); // Hash table names / sigs are indirected through to the native layout info - MethodNameAndSignature nameAndSignature; - if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out nameAndSignature)) - return false; + MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned()); RuntimeTypeHandle[] parsedArgsHandles = GetTypeSequence(ref externalReferencesLookup, ref entryParser); @@ -188,12 +186,26 @@ internal bool TryLookupGenericMethodDictionary(GenericMethodLookupData lookupDat public bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles) { if (!TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles)) - if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles)) + { + if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out TypeManagerHandle typeManager, out uint nameAndSigOffset, out genericMethodArgumentHandles)) return false; + nameAndSignature = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(typeManager, nameAndSigOffset); + } + return true; } + public bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out RuntimeTypeHandle[] genericMethodArgumentHandles) + { + if (!TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out _, out genericMethodArgumentHandles)) + if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out _, out _, out genericMethodArgumentHandles)) + return false; + + return true; + } + + public bool TryLookupExactMethodPointer(InstantiatedMethod method, out IntPtr result) { int lookupHashcode = method.OwningType.GetHashCode(); @@ -351,7 +363,7 @@ private bool TryGetDynamicGenericMethodComponents(IntPtr methodDictionary, out R return true; } } - private unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature methodNameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles) + private unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out TypeManagerHandle typeManager, out uint nameAndSigOffset, out RuntimeTypeHandle[] genericMethodArgumentHandles) { // Generic method dictionaries have a header that has the hash code in it. Locate the header IntPtr dictionaryHeader = IntPtr.Subtract(methodDictionary, IntPtr.Size); @@ -379,9 +391,8 @@ private unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, // We have a match - fill in the results declaringType = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); - // Hash table names / sigs are indirected through to the native layout info - if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(module.Handle, entryParser.GetUnsigned(), out methodNameAndSignature)) - continue; + typeManager = module.Handle; + nameAndSigOffset = entryParser.GetUnsigned(); uint arity = entryParser.GetSequenceCount(); genericMethodArgumentHandles = new RuntimeTypeHandle[arity]; @@ -396,7 +407,8 @@ private unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, } declaringType = default(RuntimeTypeHandle); - methodNameAndSignature = null; + typeManager = default; + nameAndSigOffset = 0; genericMethodArgumentHandles = null; return false; } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs index 176e7335cc755..3ec00d4bfd09b 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs @@ -651,13 +651,7 @@ public static bool TryGetVirtualResolveData(NativeFormatModuleInfo module, uint nameAndSigPointerToken = entryParser.GetUnsigned(); - MethodNameAndSignature nameAndSig; - if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(module.Handle, nameAndSigPointerToken, out nameAndSig)) - { - Debug.Assert(false); - continue; - } - + MethodNameAndSignature nameAndSig = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(module.Handle, nameAndSigPointerToken); if (!methodSignatureComparer.IsMatchingNativeLayoutMethodNameAndSignature(nameAndSig.Name, nameAndSig.Signature)) { continue; @@ -972,12 +966,7 @@ public void GetNext( else { uint nameAndSigToken = entryParser.GetUnsigned(); - MethodNameAndSignature nameAndSig; - if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigToken, out nameAndSig)) - { - Debug.Assert(false); - return; - } + MethodNameAndSignature nameAndSig = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigToken); Debug.Assert(nameAndSig.Signature.IsNativeLayoutSignature); if (!methodSignatureComparer.IsMatchingNativeLayoutMethodNameAndSignature(nameAndSig.Name, nameAndSig.Signature)) return; @@ -1004,11 +993,7 @@ public void GetNext( Debug.Assert((_hasEntryPoint || ((_flags & InvokeTableFlags.HasVirtualInvoke) != 0)) && ((_flags & InvokeTableFlags.RequiresInstArg) != 0)); uint nameAndSigPointerToken = entryParser.GetUnsigned(); - if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigPointerToken, out _nameAndSignature)) - { - Debug.Assert(false); //Error - _isMatchingMethodHandleAndDeclaringType = false; - } + _nameAndSignature = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigPointerToken); } else if (((_flags & InvokeTableFlags.RequiresInstArg) != 0) && _hasEntryPoint) _entryDictionary = extRefTable.GetGenericDictionaryFromIndex(entryParser.GetUnsigned()); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.SignatureParsing.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.SignatureParsing.cs index 23864032346e4..f7b7f5b8fcbbf 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.SignatureParsing.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.SignatureParsing.cs @@ -138,17 +138,11 @@ public bool TryGetMethodNameAndSignaturePointersFromNativeLayoutSignature(TypeMa return true; } - public bool TryGetMethodNameAndSignatureFromNativeLayoutOffset(TypeManagerHandle moduleHandle, uint nativeLayoutOffset, out MethodNameAndSignature nameAndSignature) + public MethodNameAndSignature GetMethodNameAndSignatureFromNativeLayoutOffset(TypeManagerHandle moduleHandle, uint nativeLayoutOffset) { - nameAndSignature = null; - NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, nativeLayoutOffset); - if (parser.IsNull) - return false; - - nameAndSignature = GetMethodNameAndSignature(ref parser, moduleHandle, out _, out _); - return true; + return GetMethodNameAndSignature(ref parser, moduleHandle, out _, out _); } internal static MethodNameAndSignature GetMethodNameAndSignature(ref NativeParser parser, TypeManagerHandle moduleHandle, out RuntimeSignature methodNameSig, out RuntimeSignature methodSig) diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs index 58a4de298e974..98c561f3eddd1 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs @@ -20,18 +20,22 @@ static int Main() Console.WriteLine($"* Size of the executable is {fileSize / 1024,7:n0} kB *"); Console.WriteLine("****************************************************"); - const int Meg = 1024 * 1024; - const int HalfMeg = Meg / 2; long lowerBound, upperBound; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { + const int Meg = 1024 * 1024; lowerBound = 2 * Meg; // 2 MB upperBound = 4 * Meg; // 4 MB } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + lowerBound = 1300 * 1024; // ~1.3 MB + upperBound = 1600 * 1024; // ~1.6 MB + } else { - lowerBound = Meg + HalfMeg; // 1.5 MB - upperBound = 2 * Meg; // 2 MB + lowerBound = 1500 * 1024; // ~1.5 MB + upperBound = 1900 * 1024; // ~1.9 MB } if (fileSize < lowerBound || fileSize > upperBound)