Skip to content

Commit b06b325

Browse files
authored
[NativeAOT] Replace GVMLookupForSlot internal cache with generic cache similar to CastCache (#89331)
* factored out CastCache to be able create several. * Cache impl * generic cache * some refactoring * separated GenericCache * comments * less refs * do not store hash * fix CoreCLR and some more refactoring * PR feedback * remove no longer needed CastCache wrapping constructor * remove auto-inserted unused usings. * remove unused ActivatorCreateInstanceAny
1 parent 4964d54 commit b06b325

File tree

9 files changed

+614
-314
lines changed

9 files changed

+614
-314
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ namespace System.Runtime.CompilerServices
1111
{
1212
internal static unsafe class CastHelpers
1313
{
14+
// In coreclr the table is allocated and written to on the native side.
15+
internal static int[]? s_table;
16+
1417
[MethodImpl(MethodImplOptions.InternalCall)]
1518
private static extern object IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj);
1619

@@ -36,7 +39,7 @@ internal static unsafe class CastHelpers
3639
void* mt = RuntimeHelpers.GetMethodTable(obj);
3740
if (mt != toTypeHnd)
3841
{
39-
CastResult result = CastCache.TryGet((nuint)mt, (nuint)toTypeHnd);
42+
CastResult result = CastCache.TryGet(s_table!, (nuint)mt, (nuint)toTypeHnd);
4043
if (result == CastResult.CanCast)
4144
{
4245
// do nothing
@@ -186,7 +189,7 @@ internal static unsafe class CastHelpers
186189
[MethodImpl(MethodImplOptions.NoInlining)]
187190
private static object? IsInstance_Helper(void* toTypeHnd, object obj)
188191
{
189-
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
192+
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
190193
if (result == CastResult.CanCast)
191194
{
192195
return obj;
@@ -215,7 +218,7 @@ internal static unsafe class CastHelpers
215218
void* mt = RuntimeHelpers.GetMethodTable(obj);
216219
if (mt != toTypeHnd)
217220
{
218-
result = CastCache.TryGet((nuint)mt, (nuint)toTypeHnd);
221+
result = CastCache.TryGet(s_table!, (nuint)mt, (nuint)toTypeHnd);
219222
if (result != CastResult.CanCast)
220223
{
221224
goto slowPath;
@@ -239,7 +242,7 @@ internal static unsafe class CastHelpers
239242
[MethodImpl(MethodImplOptions.NoInlining)]
240243
private static object? ChkCast_Helper(void* toTypeHnd, object obj)
241244
{
242-
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
245+
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
243246
if (result == CastResult.CanCast)
244247
{
245248
return obj;
@@ -456,7 +459,7 @@ private static void StelemRef(Array array, nint index, object? obj)
456459
[MethodImpl(MethodImplOptions.NoInlining)]
457460
private static void StelemRef_Helper(ref object? element, void* elementType, object obj)
458461
{
459-
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)elementType);
462+
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)elementType);
460463
if (result == CastResult.CanCast)
461464
{
462465
WriteBarrier(ref element, obj);

src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,19 @@ namespace System.Runtime
2121
//
2222
/////////////////////////////////////////////////////////////////////////////////////////////////////
2323

24+
[EagerStaticClassConstruction]
2425
internal static class TypeCast
2526
{
27+
#if DEBUG
28+
private const int InitialCacheSize = 8; // MUST BE A POWER OF TWO
29+
private const int MaximumCacheSize = 512; // make this lower than release to make it easier to reach this in tests.
30+
#else
31+
private const int InitialCacheSize = 128; // MUST BE A POWER OF TWO
32+
private const int MaximumCacheSize = 4096; // 4096 * sizeof(CastCacheEntry) is 98304 bytes on 64bit. We will rarely need this much though.
33+
#endif // DEBUG
34+
35+
private static CastCache s_castCache = new CastCache(InitialCacheSize, MaximumCacheSize);
36+
2637
[Flags]
2738
internal enum AssignmentVariation
2839
{
@@ -1159,7 +1170,7 @@ public static unsafe bool AreTypesAssignableInternal(MethodTable* pSourceType, M
11591170
return true;
11601171

11611172
nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
1162-
CastResult result = CastCache.TryGet(sourceAndVariation, (nuint)(pTargetType));
1173+
CastResult result = s_castCache.TryGet(sourceAndVariation, (nuint)(pTargetType));
11631174
if (result != CastResult.MaybeCast)
11641175
{
11651176
return result == CastResult.CanCast;
@@ -1187,7 +1198,7 @@ private static unsafe bool CacheMiss(MethodTable* pSourceType, MethodTable* pTar
11871198
// Update the cache
11881199
//
11891200
nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
1190-
CastCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);
1201+
s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);
11911202

11921203
return result;
11931204
}

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LibraryInitializer.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public static void InitializeLibrary()
1919
{
2020
PreallocatedOutOfMemoryException.Initialize();
2121
ClassConstructorRunner.Initialize();
22-
TypeLoaderExports.Initialize();
2322
}
2423
}
2524
}

0 commit comments

Comments
 (0)