Skip to content

Commit

Permalink
[NativeAOT] Replace GVMLookupForSlot internal cache with generic cach…
Browse files Browse the repository at this point in the history
…e 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
  • Loading branch information
VSadov committed Jul 24, 2023
1 parent 4964d54 commit b06b325
Show file tree
Hide file tree
Showing 9 changed files with 614 additions and 314 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ namespace System.Runtime.CompilerServices
{
internal static unsafe class CastHelpers
{
// In coreclr the table is allocated and written to on the native side.
internal static int[]? s_table;

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj);

Expand All @@ -36,7 +39,7 @@ internal static unsafe class CastHelpers
void* mt = RuntimeHelpers.GetMethodTable(obj);
if (mt != toTypeHnd)
{
CastResult result = CastCache.TryGet((nuint)mt, (nuint)toTypeHnd);
CastResult result = CastCache.TryGet(s_table!, (nuint)mt, (nuint)toTypeHnd);
if (result == CastResult.CanCast)
{
// do nothing
Expand Down Expand Up @@ -186,7 +189,7 @@ internal static unsafe class CastHelpers
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? IsInstance_Helper(void* toTypeHnd, object obj)
{
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
if (result == CastResult.CanCast)
{
return obj;
Expand Down Expand Up @@ -215,7 +218,7 @@ internal static unsafe class CastHelpers
void* mt = RuntimeHelpers.GetMethodTable(obj);
if (mt != toTypeHnd)
{
result = CastCache.TryGet((nuint)mt, (nuint)toTypeHnd);
result = CastCache.TryGet(s_table!, (nuint)mt, (nuint)toTypeHnd);
if (result != CastResult.CanCast)
{
goto slowPath;
Expand All @@ -239,7 +242,7 @@ internal static unsafe class CastHelpers
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? ChkCast_Helper(void* toTypeHnd, object obj)
{
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)toTypeHnd);
if (result == CastResult.CanCast)
{
return obj;
Expand Down Expand Up @@ -456,7 +459,7 @@ private static void StelemRef(Array array, nint index, object? obj)
[MethodImpl(MethodImplOptions.NoInlining)]
private static void StelemRef_Helper(ref object? element, void* elementType, object obj)
{
CastResult result = CastCache.TryGet((nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)elementType);
CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)elementType);
if (result == CastResult.CanCast)
{
WriteBarrier(ref element, obj);
Expand Down
15 changes: 13 additions & 2 deletions src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@ namespace System.Runtime
//
/////////////////////////////////////////////////////////////////////////////////////////////////////

[EagerStaticClassConstruction]
internal static class TypeCast
{
#if DEBUG
private const int InitialCacheSize = 8; // MUST BE A POWER OF TWO
private const int MaximumCacheSize = 512; // make this lower than release to make it easier to reach this in tests.
#else
private const int InitialCacheSize = 128; // MUST BE A POWER OF TWO
private const int MaximumCacheSize = 4096; // 4096 * sizeof(CastCacheEntry) is 98304 bytes on 64bit. We will rarely need this much though.
#endif // DEBUG

private static CastCache s_castCache = new CastCache(InitialCacheSize, MaximumCacheSize);

[Flags]
internal enum AssignmentVariation
{
Expand Down Expand Up @@ -1159,7 +1170,7 @@ public static unsafe bool AreTypesAssignableInternal(MethodTable* pSourceType, M
return true;

nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
CastResult result = CastCache.TryGet(sourceAndVariation, (nuint)(pTargetType));
CastResult result = s_castCache.TryGet(sourceAndVariation, (nuint)(pTargetType));
if (result != CastResult.MaybeCast)
{
return result == CastResult.CanCast;
Expand Down Expand Up @@ -1187,7 +1198,7 @@ private static unsafe bool CacheMiss(MethodTable* pSourceType, MethodTable* pTar
// Update the cache
//
nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
CastCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);
s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public static void InitializeLibrary()
{
PreallocatedOutOfMemoryException.Initialize();
ClassConstructorRunner.Initialize();
TypeLoaderExports.Initialize();
}
}
}
Loading

0 comments on commit b06b325

Please sign in to comment.