-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- It was only used for overflow scenarios from the generic dictionary (which don't happen), virtual resolution scenarios for creating delegates, and a few other rare R2R scenarios - Replace the virtual resolution scenarios with a cache of the affected data in managed code, and move the helpers to managed - Just remove the pointless checks from within the various normal generic lookup paths Swap to using GenericCache - Make FlushCurrentCache public on GenericCache, as we need to clear this when we clean up a LoaderAllocator - Tweak algorithm for computing out of bound slots on the DictionaryLayout Update crsttypes
- Loading branch information
1 parent
56435ad
commit 7de3762
Showing
15 changed files
with
195 additions
and
374 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
...eclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/VirtualDispatchHelpers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Numerics; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace System.Runtime.CompilerServices; | ||
|
||
[StackTraceHidden] | ||
[DebuggerStepThrough] | ||
internal static unsafe partial class VirtualDispatchHelpers | ||
{ | ||
private struct VirtualResolutionData : IEquatable<VirtualResolutionData> | ||
{ | ||
public MethodTable* MethodTable; | ||
public IntPtr ClassHandleTargetMethod; | ||
public IntPtr MethodHandle; | ||
|
||
public bool Equals(VirtualResolutionData other) => | ||
MethodTable == other.MethodTable && | ||
ClassHandleTargetMethod == other.ClassHandleTargetMethod && | ||
MethodHandle == other.MethodHandle; | ||
|
||
public override bool Equals(object? obj) => obj is VirtualResolutionData other && Equals(other); | ||
|
||
public override int GetHashCode() => (int) ((uint)MethodTable ^ (BitOperations.RotateLeft((uint)ClassHandleTargetMethod, 5)) ^ (BitOperations.RotateRight((uint)MethodHandle, 5))); | ||
} | ||
|
||
private struct VirtualFunctionPointerArgs | ||
{ | ||
public IntPtr classHnd; | ||
public IntPtr methodHnd; | ||
}; | ||
|
||
#if DEBUG | ||
// use smaller numbers to hit resizing/preempting logic in debug | ||
private const int InitialCacheSize = 8; // MUST BE A POWER OF TWO | ||
private const int MaximumCacheSize = 512; | ||
#else | ||
private const int InitialCacheSize = 128; // MUST BE A POWER OF TWO | ||
private const int MaximumCacheSize = 8 * 1024; | ||
#endif // DEBUG | ||
|
||
private static GenericCache<VirtualResolutionData, IntPtr> s_virtualFunctionPointerCache = new GenericCache<VirtualResolutionData, IntPtr>(InitialCacheSize, MaximumCacheSize); | ||
|
||
internal static void ClearCache() | ||
{ | ||
s_virtualFunctionPointerCache.FlushCurrentCache(); | ||
} | ||
|
||
[LibraryImport(RuntimeHelpers.QCall)] | ||
private static unsafe partial IntPtr JIT_ResolveVirtualFunctionPointer(ObjectHandleOnStack obj, IntPtr classHandle, IntPtr methodHandle); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
[DebuggerHidden] | ||
private static unsafe IntPtr VirtualFunctionPointerSlowpath(object obj, IntPtr classHandle, IntPtr methodHandle) | ||
{ | ||
IntPtr result = JIT_ResolveVirtualFunctionPointer(ObjectHandleOnStack.Create(ref obj), classHandle, methodHandle); | ||
s_virtualFunctionPointerCache.TrySet(new VirtualResolutionData { MethodTable = RuntimeHelpers.GetMethodTable(obj), ClassHandleTargetMethod = classHandle, MethodHandle = methodHandle }, result); | ||
GC.KeepAlive(obj); | ||
return result; | ||
} | ||
|
||
[DebuggerHidden] | ||
private static unsafe IntPtr VirtualFunctionPointer(object obj, IntPtr classHandle, IntPtr methodHandle) | ||
{ | ||
if (s_virtualFunctionPointerCache.TryGet(new VirtualResolutionData { MethodTable = RuntimeHelpers.GetMethodTable(obj), ClassHandleTargetMethod = classHandle, MethodHandle = methodHandle }, out IntPtr result)) | ||
{ | ||
return result; | ||
} | ||
return VirtualFunctionPointerSlowpath(obj, classHandle, methodHandle); | ||
} | ||
|
||
[DebuggerHidden] | ||
private static unsafe IntPtr VirtualFunctionPointer_Dynamic(object obj, ref VirtualFunctionPointerArgs virtualFunctionPointerArgs) | ||
{ | ||
IntPtr classHandle = virtualFunctionPointerArgs.classHnd; | ||
IntPtr methodHandle = virtualFunctionPointerArgs.methodHnd; | ||
|
||
if (s_virtualFunctionPointerCache.TryGet(new VirtualResolutionData { MethodTable = RuntimeHelpers.GetMethodTable(obj), ClassHandleTargetMethod = classHandle, MethodHandle = methodHandle }, out IntPtr result)) | ||
{ | ||
return result; | ||
} | ||
return VirtualFunctionPointerSlowpath(obj, classHandle, methodHandle); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
/*============================================================ | ||
** | ||
** Header: VirtualFunctionHelpers.h | ||
** | ||
** | ||
===========================================================*/ | ||
|
||
#ifndef _VIRTUALFUNCTIONHELPERS_H | ||
#define _VIRTUALFUNCTIONHELPERS_H | ||
|
||
#include "qcall.h" | ||
#include "corinfo.h" | ||
|
||
extern "C" void * QCALLTYPE JIT_ResolveVirtualFunctionPointer(QCall::ObjectHandleOnStack obj, CORINFO_CLASS_HANDLE classHnd, CORINFO_METHOD_HANDLE methodHnd); | ||
|
||
#endif //_VIRTUALFUNCTIONHELPERS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.