From d0c94572ffa83d94dd6ca68862a1faf406f2863c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 9 May 2023 06:08:59 +0900 Subject: [PATCH] Speed up `GVMLookupForSlot` (#85901) BasicMinimalApi spends about 1% of samples in this method. --- .../src/System/Runtime/TypeLoaderExports.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs index 0c15531..431c83b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs @@ -110,10 +110,19 @@ namespace System.Runtime public static unsafe IntPtr GVMLookupForSlot(object obj, RuntimeMethodHandle slot) { - Entry entry = LookupInCache(s_cache, (IntPtr)obj.GetMethodTable(), *(IntPtr*)&slot); - entry ??= CacheMiss((IntPtr)obj.GetMethodTable(), *(IntPtr*)&slot, + Entry entry = LookupInCache(s_cache, (IntPtr)obj.GetMethodTable(), RuntimeMethodHandle.ToIntPtr(slot)); + if (entry != null) + return entry.Result; + + return GVMLookupForSlotSlow(obj, slot); + } + + private static unsafe IntPtr GVMLookupForSlotSlow(object obj, RuntimeMethodHandle slot) + { + Entry entry = CacheMiss((IntPtr)obj.GetMethodTable(), RuntimeMethodHandle.ToIntPtr(slot), (IntPtr context, IntPtr signature, object contextObject, ref IntPtr auxResult) => RuntimeAugments.TypeLoaderCallbacks.ResolveGenericVirtualMethodTarget(new RuntimeTypeHandle(new EETypePtr(context)), *(RuntimeMethodHandle*)&signature)); + return entry.Result; } @@ -132,7 +141,11 @@ namespace System.Runtime private static Entry LookupInCache(Entry[] cache, IntPtr context, IntPtr signature) { int key = ((context.GetHashCode() >> 4) ^ signature.GetHashCode()) & (cache.Length - 1); +#if DEBUG Entry entry = cache[key]; +#else + Entry entry = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(cache), key); +#endif while (entry != null) { if (entry.Context == context && entry.Signature == signature) -- 2.7.4