Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgor Bogatov <egorbo@gmail.com>2021-02-12 19:56:39 +0300
committerGitHub <noreply@github.com>2021-02-12 19:56:39 +0300
commita08fec6608cc31734d358581c6eaea45b1600a64 (patch)
tree1dd3c1f83e5d05b1c568d6d7e7e941257b511903
parent3844c76b37b197cdef1b8fcce423964fffe188cd (diff)
[RyuJIT] Devirtualize Comparer<T>.Default (#48160)
-rw-r--r--src/coreclr/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreCLR.cs2
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp17
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h7
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp10
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp7
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp6
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp9
-rw-r--r--src/coreclr/inc/corinfo.h6
-rw-r--r--src/coreclr/inc/icorjitinfoimpl_generated.h3
-rw-r--r--src/coreclr/inc/jiteeversionguid.h10
-rw-r--r--src/coreclr/jit/ICorJitInfo_API_names.h1
-rw-r--r--src/coreclr/jit/ICorJitInfo_API_wrapper.hpp9
-rw-r--r--src/coreclr/jit/flowgraph.cpp7
-rw-r--r--src/coreclr/jit/importer.cpp16
-rw-r--r--src/coreclr/jit/namedintrinsiclist.h1
-rw-r--r--src/coreclr/tools/Common/JitInterface/CorInfoBase.cs332
-rw-r--r--src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs7
-rw-r--r--src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt1
-rw-r--r--src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs8
-rw-r--r--src/coreclr/tools/aot/jitinterface/jitinterface.h10
-rw-r--r--src/coreclr/vm/corelib.h7
-rw-r--r--src/coreclr/vm/jitinterface.cpp98
-rw-r--r--src/coreclr/vm/jitinterface.h4
-rw-r--r--src/coreclr/zap/zapinfo.cpp6
-rw-r--r--src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs1
-rw-r--r--src/tests/JIT/opt/Devirtualization/Comparer_get_Default.cs244
-rw-r--r--src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj9
-rw-r--r--src/tests/issues.targets3
29 files changed, 672 insertions, 170 deletions
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreCLR.cs
index 1af5fca4702..a2790cbd121 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreCLR.cs
@@ -10,7 +10,7 @@ namespace System.Collections.Generic
{
// To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
// as possible and define most of the creation logic in a non-generic class.
- public static Comparer<T> Default { get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
+ public static Comparer<T> Default { [Intrinsic] get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
}
internal sealed partial class EnumComparer<T> : Comparer<T> where T : struct, Enum
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
index 18948eafc4c..961514d847d 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -74,6 +74,7 @@ LWM(GetClassSize, DWORDLONG, DWORD)
LWM(GetHeapClassSize, DWORDLONG, DWORD)
LWM(CanAllocateOnStack, DWORDLONG, DWORD)
LWM(GetCookieForPInvokeCalliSig, GetCookieForPInvokeCalliSigValue, DLDL)
+LWM(GetDefaultComparerClass, DWORDLONG, DWORDLONG)
LWM(GetDefaultEqualityComparerClass, DWORDLONG, DWORDLONG)
LWM(GetDelegateCtor, Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut)
LWM(GetEEInfo, DWORD, Agnostic_CORINFO_EE_INFO)
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 3b57ce0aa9c..38d954f7d3b 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -3101,6 +3101,23 @@ CORINFO_METHOD_HANDLE MethodContext::repGetUnboxedEntry(CORINFO_METHOD_HANDLE ft
return (CORINFO_METHOD_HANDLE)(result.A);
}
+void MethodContext::recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result)
+{
+ if (GetDefaultComparerClass == nullptr)
+ GetDefaultComparerClass = new LightWeightMap<DWORDLONG, DWORDLONG>();
+
+ GetDefaultComparerClass->Add(CastHandle(cls), CastHandle(result));
+}
+void MethodContext::dmpGetDefaultComparerClass(DWORDLONG key, DWORDLONG value)
+{
+ printf("GetDefaultComparerClass key cls-%016llX, value cls-%016llX", key, value);
+}
+CORINFO_CLASS_HANDLE MethodContext::repGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls)
+{
+ CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)GetDefaultComparerClass->Get(CastHandle(cls));
+ return result;
+}
+
void MethodContext::recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result)
{
if (GetDefaultEqualityComparerClass == nullptr)
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 0bf0cfaa8ef..d45b4df3672 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -401,6 +401,10 @@ public:
void dmpGetUnboxedEntry(DWORDLONG key, DLD value);
CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg);
+ void recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
+ void dmpGetDefaultComparerClass(DWORDLONG key, DWORDLONG value);
+ CORINFO_CLASS_HANDLE repGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls);
+
void recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
void dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value);
CORINFO_CLASS_HANDLE repGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls);
@@ -867,7 +871,7 @@ private:
};
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 187
+// Highest packet number: 188
// *************************************************************************************
enum mcPackets
{
@@ -943,6 +947,7 @@ enum mcPackets
Packet_GetIntConfigValue = 151, // Added 2/12/2015
Packet_GetStringConfigValue = 152, // Added 2/12/2015
Packet_GetCookieForPInvokeCalliSig = 48,
+ Packet_GetDefaultComparerClass = 188, // Added 2/10/2021
Packet_GetDefaultEqualityComparerClass = 162, // Added 9/24/2017
Packet_GetDelegateCtor = 49,
Packet_GetEEInfo = 50,
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index 6f07edb6a9d..045037565d4 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -252,6 +252,16 @@ CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ft
return result;
}
+// Given T, return the type of the default Comparer<T>.
+// Returns null if the type can't be determined exactly.
+CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultComparerClass(CORINFO_CLASS_HANDLE cls)
+{
+ mc->cr->AddCall("getDefaultComparerClass");
+ CORINFO_CLASS_HANDLE result = original_ICorJitInfo->getDefaultComparerClass(cls);
+ mc->recGetDefaultComparerClass(cls, result);
+ return result;
+}
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls)
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 6945b6d74d3..1f832798ce3 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -132,6 +132,13 @@ CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(
return original_ICorJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
}
+CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType)
+{
+ mcs->AddCall("getDefaultComparerClass");
+ return original_ICorJitInfo->getDefaultComparerClass(elemType);
+}
+
CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(
CORINFO_CLASS_HANDLE elemType)
{
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index 1d73a9759c6..373b21ffa52 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -118,6 +118,12 @@ CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(
return original_ICorJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
}
+CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType)
+{
+ return original_ICorJitInfo->getDefaultComparerClass(elemType);
+}
+
CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(
CORINFO_CLASS_HANDLE elemType)
{
diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index 5e85ded0486..6e5086b0365 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -186,6 +186,15 @@ CORINFO_METHOD_HANDLE MyICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* r
return result;
}
+// Given T, return the type of the default Comparer<T>.
+// Returns null if the type can't be determined exactly.
+CORINFO_CLASS_HANDLE MyICJI::getDefaultComparerClass(CORINFO_CLASS_HANDLE cls)
+{
+ jitInstance->mc->cr->AddCall("getDefaultComparerClass");
+ CORINFO_CLASS_HANDLE result = jitInstance->mc->repGetDefaultComparerClass(cls);
+ return result;
+}
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE MyICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls)
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index 97e044fc895..6d2e881f628 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -2057,6 +2057,12 @@ public:
bool* requiresInstMethodTableArg
) = 0;
+ // Given T, return the type of the default Comparer<T>.
+ // Returns null if the type can't be determined exactly.
+ virtual CORINFO_CLASS_HANDLE getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType
+ ) = 0;
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
virtual CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(
diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h
index 20219a094d6..e02a50993b5 100644
--- a/src/coreclr/inc/icorjitinfoimpl_generated.h
+++ b/src/coreclr/inc/icorjitinfoimpl_generated.h
@@ -85,6 +85,9 @@ CORINFO_METHOD_HANDLE getUnboxedEntry(
CORINFO_METHOD_HANDLE ftn,
bool* requiresInstMethodTableArg) override;
+CORINFO_CLASS_HANDLE getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType) override;
+
CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(
CORINFO_CLASS_HANDLE elemType) override;
diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h
index 6c2aeea227b..8cc074bf578 100644
--- a/src/coreclr/inc/jiteeversionguid.h
+++ b/src/coreclr/inc/jiteeversionguid.h
@@ -32,11 +32,11 @@
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
-constexpr GUID JITEEVersionIdentifier = { /* 20017875-6552-4375-80A8-F7E2CFC6AAB7 */
- 0x20017875,
- 0x6552,
- 0x4375,
- { 0x80, 0xa8, 0xf7, 0xe2, 0xcf, 0xc6, 0xaa, 0xb7 }
+constexpr GUID JITEEVersionIdentifier = { /* 6ca59d19-13a4-44f7-a184-e9cd1e8f57f8 */
+ 0x6ca59d19,
+ 0x13a4,
+ 0x44f7,
+ { 0xa1, 0x84, 0xe9, 0xcd, 0x1e, 0x8f, 0x57, 0xf8 }
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h
index 1c74f8b96ae..2e1e67cc24a 100644
--- a/src/coreclr/jit/ICorJitInfo_API_names.h
+++ b/src/coreclr/jit/ICorJitInfo_API_names.h
@@ -18,6 +18,7 @@ DEF_CLR_API(getMethodModule)
DEF_CLR_API(getMethodVTableOffset)
DEF_CLR_API(resolveVirtualMethod)
DEF_CLR_API(getUnboxedEntry)
+DEF_CLR_API(getDefaultComparerClass)
DEF_CLR_API(getDefaultEqualityComparerClass)
DEF_CLR_API(expandRawHandleIntrinsic)
DEF_CLR_API(getIntrinsicID)
diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp
index 42d2b55b730..ccae8f7096d 100644
--- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp
+++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp
@@ -154,6 +154,15 @@ CORINFO_METHOD_HANDLE WrapICorJitInfo::getUnboxedEntry(
return temp;
}
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType)
+{
+ API_ENTER(getDefaultComparerClass);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getDefaultComparerClass(elemType);
+ API_LEAVE(getDefaultComparerClass);
+ return temp;
+}
+
CORINFO_CLASS_HANDLE WrapICorJitInfo::getDefaultEqualityComparerClass(
CORINFO_CLASS_HANDLE elemType)
{
diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp
index 594a59af14e..d6a9ed7642b 100644
--- a/src/coreclr/jit/flowgraph.cpp
+++ b/src/coreclr/jit/flowgraph.cpp
@@ -926,13 +926,14 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo
GenTreeCall* result = gtNewHelperCallNode(helper, type, argList);
result->gtFlags |= callFlags;
- // If we're importing the special EqualityComparer<T>.Default
- // intrinsic, flag the helper call. Later during inlining, we can
+ // If we're importing the special EqualityComparer<T>.Default or Comparer<T>.Default
+ // intrinsics, flag the helper call. Later during inlining, we can
// remove the helper call if the associated field lookup is unused.
if ((info.compFlags & CORINFO_FLG_JIT_INTRINSIC) != 0)
{
NamedIntrinsic ni = lookupNamedIntrinsic(info.compMethodHnd);
- if (ni == NI_System_Collections_Generic_EqualityComparer_get_Default)
+ if ((ni == NI_System_Collections_Generic_EqualityComparer_get_Default) ||
+ (ni == NI_System_Collections_Generic_Comparer_get_Default))
{
JITDUMP("\nmarking helper call [%06u] as special dce...\n", result->gtTreeID);
result->gtCallMoreFlags |= GTF_CALL_M_HELPER_SPECIAL_DCE;
diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp
index d99c3e3bad9..2373806019f 100644
--- a/src/coreclr/jit/importer.cpp
+++ b/src/coreclr/jit/importer.cpp
@@ -4458,6 +4458,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
break;
}
+ case NI_System_Collections_Generic_Comparer_get_Default:
case NI_System_Collections_Generic_EqualityComparer_get_Default:
{
// Flag for later handling during devirtualization.
@@ -4943,6 +4944,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
{
result = NI_System_Collections_Generic_EqualityComparer_get_Default;
}
+ else if ((strcmp(className, "Comparer`1") == 0) && (strcmp(methodName, "get_Default") == 0))
+ {
+ result = NI_System_Collections_Generic_Comparer_get_Default;
+ }
}
else if ((strcmp(namespaceName, "System.Numerics") == 0) && (strcmp(className, "BitOperations") == 0))
{
@@ -21475,6 +21480,7 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(CORINFO_MET
const NamedIntrinsic ni = lookupNamedIntrinsic(methodHnd);
switch (ni)
{
+ case NI_System_Collections_Generic_Comparer_get_Default:
case NI_System_Collections_Generic_EqualityComparer_get_Default:
{
// Expect one class generic parameter; figure out which it is.
@@ -21496,7 +21502,15 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(CORINFO_MET
if (isFinalType)
{
- result = info.compCompHnd->getDefaultEqualityComparerClass(typeHnd);
+ if (ni == NI_System_Collections_Generic_EqualityComparer_get_Default)
+ {
+ result = info.compCompHnd->getDefaultEqualityComparerClass(typeHnd);
+ }
+ else
+ {
+ assert(ni == NI_System_Collections_Generic_Comparer_get_Default);
+ result = info.compCompHnd->getDefaultComparerClass(typeHnd);
+ }
JITDUMP("Special intrinsic for type %s: return type is %s\n", eeGetClassName(typeHnd),
result != nullptr ? eeGetClassName(result) : "unknown");
}
diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h
index 79214e2d395..06122ddb30a 100644
--- a/src/coreclr/jit/namedintrinsiclist.h
+++ b/src/coreclr/jit/namedintrinsiclist.h
@@ -42,6 +42,7 @@ enum NamedIntrinsic : unsigned short
NI_System_Math_Tanh,
NI_SYSTEM_MATH_END,
+ NI_System_Collections_Generic_Comparer_get_Default,
NI_System_Collections_Generic_EqualityComparer_get_Default,
NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness,
NI_System_Numerics_BitOperations_PopCount,
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs
index 3fc35919e96..80fc5e6ea34 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs
@@ -217,6 +217,21 @@ namespace Internal.JitInterface
}
[UnmanagedCallersOnly]
+ static CORINFO_CLASS_STRUCT_* _getDefaultComparerClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType)
+ {
+ var _this = GetThis(thisHandle);
+ try
+ {
+ return _this.getDefaultComparerClass(elemType);
+ }
+ catch (Exception ex)
+ {
+ *ppException = _this.AllocException(ex);
+ return default;
+ }
+ }
+
+ [UnmanagedCallersOnly]
static CORINFO_CLASS_STRUCT_* _getDefaultEqualityComparerClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType)
{
var _this = GetThis(thisHandle);
@@ -2536,7 +2551,7 @@ namespace Internal.JitInterface
static IntPtr GetUnmanagedCallbacks()
{
- void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 171);
+ void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172);
callbacks[0] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodAttribs;
callbacks[1] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CorInfoMethodRuntimeFlags, void>)&_setMethodAttribs;
@@ -2552,163 +2567,164 @@ namespace Internal.JitInterface
callbacks[11] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, uint*, bool*, void>)&_getMethodVTableOffset;
callbacks[12] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_DEVIRTUALIZATION_INFO*, byte>)&_resolveVirtualMethod;
callbacks[13] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, bool*, CORINFO_METHOD_STRUCT_*>)&_getUnboxedEntry;
- callbacks[14] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getDefaultEqualityComparerClass;
- callbacks[15] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_GENERICHANDLE_RESULT*, void>)&_expandRawHandleIntrinsic;
- callbacks[16] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, CorInfoIntrinsics>)&_getIntrinsicID;
- callbacks[17] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isIntrinsicType;
- callbacks[18] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_SIG_INFO*, bool*, CorInfoCallConvExtension>)&_getUnmanagedCallConv;
- callbacks[19] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_SIG_INFO*, byte>)&_pInvokeMarshalingRequired;
- callbacks[20] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, byte>)&_satisfiesMethodConstraints;
- callbacks[21] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, bool*, byte>)&_isCompatibleDelegate;
- callbacks[22] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_methodMustBeLoadedBeforeCodeIsRun;
- callbacks[23] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_METHOD_STRUCT_*>)&_mapMethodDeclToMethodImpl;
- callbacks[24] = (delegate* unmanaged<IntPtr, IntPtr*, IntPtr*, IntPtr**, void>)&_getGSCookie;
- callbacks[25] = (delegate* unmanaged<IntPtr, IntPtr*, PatchpointInfo*, void>)&_setPatchpointInfo;
- callbacks[26] = (delegate* unmanaged<IntPtr, IntPtr*, uint*, PatchpointInfo*>)&_getOSRInfo;
- callbacks[27] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, void>)&_resolveToken;
- callbacks[28] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte>)&_tryResolveToken;
- callbacks[29] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, CORINFO_CONTEXT_STRUCT*, CORINFO_SIG_INFO*, void>)&_findSig;
- callbacks[30] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, CORINFO_CONTEXT_STRUCT*, CORINFO_SIG_INFO*, void>)&_findCallSiteSig;
- callbacks[31] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_CLASS_STRUCT_*>)&_getTokenTypeAsHandle;
- callbacks[32] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, byte>)&_isValidToken;
- callbacks[33] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, byte>)&_isValidStringRef;
- callbacks[34] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, int*, char*>)&_getStringLiteral;
- callbacks[35] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_asCorInfoType;
- callbacks[36] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte*>)&_getClassName;
- callbacks[37] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte**, byte*>)&_getClassNameFromMetadata;
- callbacks[38] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint, CORINFO_CLASS_STRUCT_*>)&_getTypeInstantiationArgument;
- callbacks[39] = (delegate* unmanaged<IntPtr, IntPtr*, char**, int*, CORINFO_CLASS_STRUCT_*, byte, byte, byte, int>)&_appendClassName;
- callbacks[40] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isValueClass;
- callbacks[41] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoInlineTypeCheckSource, CorInfoInlineTypeCheck>)&_canInlineTypeCheck;
- callbacks[42] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassAttribs;
- callbacks[43] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isStructRequiringStackAllocRetBuf;
- callbacks[44] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_MODULE_STRUCT_*>)&_getClassModule;
- callbacks[45] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_ASSEMBLY_STRUCT_*>)&_getModuleAssembly;
- callbacks[46] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ASSEMBLY_STRUCT_*, byte*>)&_getAssemblyName;
- callbacks[47] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_LongLifetimeMalloc;
- callbacks[48] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_LongLifetimeFree;
- callbacks[49] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_MODULE_STRUCT_**, void**, UIntPtr>)&_getClassModuleIdForStatics;
- callbacks[50] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassSize;
- callbacks[51] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getHeapClassSize;
- callbacks[52] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_canAllocateOnStack;
- callbacks[53] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte, uint>)&_getClassAlignmentRequirement;
- callbacks[54] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte*, uint>)&_getClassGClayout;
- callbacks[55] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassNumInstanceFields;
- callbacks[56] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, int, CORINFO_FIELD_STRUCT_*>)&_getFieldInClass;
- callbacks[57] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, byte, byte>)&_checkMethodModifier;
- callbacks[58] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, bool*, CorInfoHelpFunc>)&_getNewHelper;
- callbacks[59] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getNewArrHelper;
- callbacks[60] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CorInfoHelpFunc>)&_getCastingHelper;
- callbacks[61] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getSharedCCtorHelper;
- callbacks[62] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getTypeForBox;
- callbacks[63] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getBoxHelper;
- callbacks[64] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getUnBoxHelper;
- callbacks[65] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_LOOKUP_KIND*, CorInfoHelpFunc, CORINFO_CONST_LOOKUP*, byte>)&_getReadyToRunHelper;
- callbacks[66] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_CLASS_STRUCT_*, CORINFO_LOOKUP*, void>)&_getReadyToRunDelegateCtorHelper;
- callbacks[67] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, byte*>)&_getHelperName;
- callbacks[68] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_METHOD_STRUCT_*, CORINFO_CONTEXT_STRUCT*, CorInfoInitClassResult>)&_initClass;
- callbacks[69] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void>)&_classMustBeLoadedBeforeCodeIsRun;
- callbacks[70] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoClassId, CORINFO_CLASS_STRUCT_*>)&_getBuiltinClass;
- callbacks[71] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveValueClass;
- callbacks[72] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveNumericClass;
- callbacks[73] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canCast;
- callbacks[74] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_areTypesEquivalent;
- callbacks[75] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForCast;
- callbacks[76] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForEquality;
- callbacks[77] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_mergeClasses;
- callbacks[78] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_isMoreSpecificType;
- callbacks[79] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getParentType;
- callbacks[80] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoType>)&_getChildType;
- callbacks[81] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_satisfiesClassConstraints;
- callbacks[82] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isSDArray;
- callbacks[83] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getArrayRank;
- callbacks[84] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint, void*>)&_getArrayInitializationData;
- callbacks[85] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_HELPER_DESC*, CorInfoIsAccessAllowedResult>)&_canAccessClass;
- callbacks[86] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte**, byte*>)&_getFieldName;
- callbacks[87] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getFieldClass;
- callbacks[88] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_**, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getFieldType;
- callbacks[89] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getFieldOffset;
- callbacks[90] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_ACCESS_FLAGS, CORINFO_FIELD_INFO*, void>)&_getFieldInfo;
- callbacks[91] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte>)&_isFieldStatic;
- callbacks[92] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, uint**, BoundaryTypes*, void>)&_getBoundaries;
- callbacks[93] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, OffsetMapping*, void>)&_setBoundaries;
- callbacks[94] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, ILVarInfo**, bool*, void>)&_getVars;
- callbacks[95] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, NativeVarInfo*, void>)&_setVars;
- callbacks[96] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocateArray;
- callbacks[97] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_freeArray;
- callbacks[98] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_ARG_LIST_STRUCT_*>)&_getArgNext;
- callbacks[99] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoTypeWithMod>)&_getArgType;
- callbacks[100] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getArgClass;
- callbacks[101] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHFAElemType>)&_getHFAType;
- callbacks[102] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, HRESULT>)&_GetErrorHRESULT;
- callbacks[103] = (delegate* unmanaged<IntPtr, IntPtr*, char*, uint, uint>)&_GetErrorMessage;
- callbacks[104] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, int>)&_FilterException;
- callbacks[105] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, void>)&_HandleException;
- callbacks[106] = (delegate* unmanaged<IntPtr, IntPtr*, HRESULT, void>)&_ThrowExceptionForJitResult;
- callbacks[107] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_HELPER_DESC*, void>)&_ThrowExceptionForHelper;
- callbacks[108] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithErrorTrap;
- callbacks[109] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_EE_INFO*, void>)&_getEEInfo;
- callbacks[110] = (delegate* unmanaged<IntPtr, IntPtr*, char*>)&_getJitTimeLogFilename;
- callbacks[111] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, mdToken>)&_getMethodDefFromMethod;
- callbacks[112] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte*>)&_getMethodName;
- callbacks[113] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte**, byte**, byte*>)&_getMethodNameFromMetadata;
- callbacks[114] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash;
- callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken;
- callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor;
- callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex;
- callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr;
- callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal;
- callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn;
- callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint;
- callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint;
- callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync;
- callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper;
- callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle;
- callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle;
- callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle;
- callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle;
- callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle;
- callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType;
- callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget;
- callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig;
- callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig;
- callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle;
- callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle;
- callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo;
- callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily;
- callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID;
- callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID;
- callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, void*>)&_getFieldAddress;
- callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass;
- callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle;
- callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle;
- callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral;
- callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral;
- callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID;
- callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, IntPtr, CORINFO_METHOD_STRUCT_*, void>)&_setOverride;
- callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_MODULE_STRUCT_*, void>)&_addActiveDependency;
- callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor;
- callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete;
- callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers;
- callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall;
- callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage;
- callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, uint, uint, uint, uint, CorJitAllocMemFlag, void**, void**, void**, void>)&_allocMem;
- callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo;
- callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo;
- callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo;
- callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount;
- callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo;
- callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg;
- callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert;
- callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError;
- callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, HRESULT>)&_getPgoInstrumentationResults;
- callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema;
- callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, uint, uint*, uint*, CORINFO_CLASS_STRUCT_*>)&_getLikelyClass;
- callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite;
- callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, ushort, ushort, int, void>)&_recordRelocation;
- callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint;
- callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture;
- callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags;
+ callbacks[14] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getDefaultComparerClass;
+ callbacks[15] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getDefaultEqualityComparerClass;
+ callbacks[16] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_GENERICHANDLE_RESULT*, void>)&_expandRawHandleIntrinsic;
+ callbacks[17] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, CorInfoIntrinsics>)&_getIntrinsicID;
+ callbacks[18] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isIntrinsicType;
+ callbacks[19] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_SIG_INFO*, bool*, CorInfoCallConvExtension>)&_getUnmanagedCallConv;
+ callbacks[20] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_SIG_INFO*, byte>)&_pInvokeMarshalingRequired;
+ callbacks[21] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, byte>)&_satisfiesMethodConstraints;
+ callbacks[22] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, bool*, byte>)&_isCompatibleDelegate;
+ callbacks[23] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_methodMustBeLoadedBeforeCodeIsRun;
+ callbacks[24] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_METHOD_STRUCT_*>)&_mapMethodDeclToMethodImpl;
+ callbacks[25] = (delegate* unmanaged<IntPtr, IntPtr*, IntPtr*, IntPtr**, void>)&_getGSCookie;
+ callbacks[26] = (delegate* unmanaged<IntPtr, IntPtr*, PatchpointInfo*, void>)&_setPatchpointInfo;
+ callbacks[27] = (delegate* unmanaged<IntPtr, IntPtr*, uint*, PatchpointInfo*>)&_getOSRInfo;
+ callbacks[28] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, void>)&_resolveToken;
+ callbacks[29] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte>)&_tryResolveToken;
+ callbacks[30] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, CORINFO_CONTEXT_STRUCT*, CORINFO_SIG_INFO*, void>)&_findSig;
+ callbacks[31] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, CORINFO_CONTEXT_STRUCT*, CORINFO_SIG_INFO*, void>)&_findCallSiteSig;
+ callbacks[32] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_CLASS_STRUCT_*>)&_getTokenTypeAsHandle;
+ callbacks[33] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, byte>)&_isValidToken;
+ callbacks[34] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, byte>)&_isValidStringRef;
+ callbacks[35] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, uint, int*, char*>)&_getStringLiteral;
+ callbacks[36] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_asCorInfoType;
+ callbacks[37] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte*>)&_getClassName;
+ callbacks[38] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte**, byte*>)&_getClassNameFromMetadata;
+ callbacks[39] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint, CORINFO_CLASS_STRUCT_*>)&_getTypeInstantiationArgument;
+ callbacks[40] = (delegate* unmanaged<IntPtr, IntPtr*, char**, int*, CORINFO_CLASS_STRUCT_*, byte, byte, byte, int>)&_appendClassName;
+ callbacks[41] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isValueClass;
+ callbacks[42] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoInlineTypeCheckSource, CorInfoInlineTypeCheck>)&_canInlineTypeCheck;
+ callbacks[43] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassAttribs;
+ callbacks[44] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isStructRequiringStackAllocRetBuf;
+ callbacks[45] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_MODULE_STRUCT_*>)&_getClassModule;
+ callbacks[46] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_ASSEMBLY_STRUCT_*>)&_getModuleAssembly;
+ callbacks[47] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ASSEMBLY_STRUCT_*, byte*>)&_getAssemblyName;
+ callbacks[48] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_LongLifetimeMalloc;
+ callbacks[49] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_LongLifetimeFree;
+ callbacks[50] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_MODULE_STRUCT_**, void**, UIntPtr>)&_getClassModuleIdForStatics;
+ callbacks[51] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassSize;
+ callbacks[52] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getHeapClassSize;
+ callbacks[53] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_canAllocateOnStack;
+ callbacks[54] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte, uint>)&_getClassAlignmentRequirement;
+ callbacks[55] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte*, uint>)&_getClassGClayout;
+ callbacks[56] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getClassNumInstanceFields;
+ callbacks[57] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, int, CORINFO_FIELD_STRUCT_*>)&_getFieldInClass;
+ callbacks[58] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte*, byte, byte>)&_checkMethodModifier;
+ callbacks[59] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, bool*, CorInfoHelpFunc>)&_getNewHelper;
+ callbacks[60] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getNewArrHelper;
+ callbacks[61] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CorInfoHelpFunc>)&_getCastingHelper;
+ callbacks[62] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getSharedCCtorHelper;
+ callbacks[63] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getTypeForBox;
+ callbacks[64] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getBoxHelper;
+ callbacks[65] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHelpFunc>)&_getUnBoxHelper;
+ callbacks[66] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_LOOKUP_KIND*, CorInfoHelpFunc, CORINFO_CONST_LOOKUP*, byte>)&_getReadyToRunHelper;
+ callbacks[67] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_CLASS_STRUCT_*, CORINFO_LOOKUP*, void>)&_getReadyToRunDelegateCtorHelper;
+ callbacks[68] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, byte*>)&_getHelperName;
+ callbacks[69] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_METHOD_STRUCT_*, CORINFO_CONTEXT_STRUCT*, CorInfoInitClassResult>)&_initClass;
+ callbacks[70] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void>)&_classMustBeLoadedBeforeCodeIsRun;
+ callbacks[71] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoClassId, CORINFO_CLASS_STRUCT_*>)&_getBuiltinClass;
+ callbacks[72] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveValueClass;
+ callbacks[73] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getTypeForPrimitiveNumericClass;
+ callbacks[74] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canCast;
+ callbacks[75] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_areTypesEquivalent;
+ callbacks[76] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForCast;
+ callbacks[77] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, TypeCompareState>)&_compareTypesForEquality;
+ callbacks[78] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_mergeClasses;
+ callbacks[79] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_isMoreSpecificType;
+ callbacks[80] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getParentType;
+ callbacks[81] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoType>)&_getChildType;
+ callbacks[82] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_satisfiesClassConstraints;
+ callbacks[83] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isSDArray;
+ callbacks[84] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getArrayRank;
+ callbacks[85] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint, void*>)&_getArrayInitializationData;
+ callbacks[86] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_HELPER_DESC*, CorInfoIsAccessAllowedResult>)&_canAccessClass;
+ callbacks[87] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte**, byte*>)&_getFieldName;
+ callbacks[88] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getFieldClass;
+ callbacks[89] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_**, CORINFO_CLASS_STRUCT_*, CorInfoType>)&_getFieldType;
+ callbacks[90] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, uint>)&_getFieldOffset;
+ callbacks[91] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_ACCESS_FLAGS, CORINFO_FIELD_INFO*, void>)&_getFieldInfo;
+ callbacks[92] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte>)&_isFieldStatic;
+ callbacks[93] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, uint**, BoundaryTypes*, void>)&_getBoundaries;
+ callbacks[94] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, OffsetMapping*, void>)&_setBoundaries;
+ callbacks[95] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint*, ILVarInfo**, bool*, void>)&_getVars;
+ callbacks[96] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint, NativeVarInfo*, void>)&_setVars;
+ callbacks[97] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocateArray;
+ callbacks[98] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void>)&_freeArray;
+ callbacks[99] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_ARG_LIST_STRUCT_*>)&_getArgNext;
+ callbacks[100] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_**, CorInfoTypeWithMod>)&_getArgType;
+ callbacks[101] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, CORINFO_ARG_LIST_STRUCT_*, CORINFO_CLASS_STRUCT_*>)&_getArgClass;
+ callbacks[102] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoHFAElemType>)&_getHFAType;
+ callbacks[103] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, HRESULT>)&_GetErrorHRESULT;
+ callbacks[104] = (delegate* unmanaged<IntPtr, IntPtr*, char*, uint, uint>)&_GetErrorMessage;
+ callbacks[105] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, int>)&_FilterException;
+ callbacks[106] = (delegate* unmanaged<IntPtr, IntPtr*, _EXCEPTION_POINTERS*, void>)&_HandleException;
+ callbacks[107] = (delegate* unmanaged<IntPtr, IntPtr*, HRESULT, void>)&_ThrowExceptionForJitResult;
+ callbacks[108] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_HELPER_DESC*, void>)&_ThrowExceptionForHelper;
+ callbacks[109] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, byte>)&_runWithErrorTrap;
+ callbacks[110] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_EE_INFO*, void>)&_getEEInfo;
+ callbacks[111] = (delegate* unmanaged<IntPtr, IntPtr*, char*>)&_getJitTimeLogFilename;
+ callbacks[112] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, mdToken>)&_getMethodDefFromMethod;
+ callbacks[113] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte*>)&_getMethodName;
+ callbacks[114] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte**, byte**, byte**, byte*>)&_getMethodNameFromMetadata;
+ callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash;
+ callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken;
+ callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor;
+ callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex;
+ callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr;
+ callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal;
+ callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn;
+ callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint;
+ callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint;
+ callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync;
+ callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper;
+ callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle;
+ callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle;
+ callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle;
+ callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle;
+ callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle;
+ callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType;
+ callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget;
+ callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig;
+ callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig;
+ callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle;
+ callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle;
+ callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo;
+ callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily;
+ callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID;
+ callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID;
+ callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, void*>)&_getFieldAddress;
+ callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass;
+ callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle;
+ callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle;
+ callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral;
+ callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral;
+ callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID;
+ callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, IntPtr, CORINFO_METHOD_STRUCT_*, void>)&_setOverride;
+ callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_MODULE_STRUCT_*, void>)&_addActiveDependency;
+ callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor;
+ callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete;
+ callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers;
+ callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall;
+ callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage;
+ callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, uint, uint, uint, uint, CorJitAllocMemFlag, void**, void**, void**, void>)&_allocMem;
+ callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo;
+ callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo;
+ callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo;
+ callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount;
+ callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo;
+ callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg;
+ callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert;
+ callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError;
+ callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, HRESULT>)&_getPgoInstrumentationResults;
+ callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema;
+ callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, uint, uint*, uint*, CORINFO_CLASS_STRUCT_*>)&_getLikelyClass;
+ callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite;
+ callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, ushort, ushort, int, void>)&_recordRelocation;
+ callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint;
+ callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture;
+ callbacks[171] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags;
return (IntPtr)callbacks;
}
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index 01cddcf9c37..bc56f2cda1f 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -1056,6 +1056,13 @@ namespace Internal.JitInterface
return result != null ? ObjectToHandle(result) : null;
}
+ private CORINFO_CLASS_STRUCT_* getDefaultComparerClass(CORINFO_CLASS_STRUCT_* elemType)
+ {
+ TypeDesc comparand = HandleToObject(elemType);
+ TypeDesc comparer = IL.Stubs.ComparerIntrinsics.GetComparerForType(comparand);
+ return comparer != null ? ObjectToHandle(comparer) : null;
+ }
+
private CORINFO_CLASS_STRUCT_* getDefaultEqualityComparerClass(CORINFO_CLASS_STRUCT_* elemType)
{
TypeDesc comparand = HandleToObject(elemType);
diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt
index 1b6b4e8f259..7824fae24b4 100644
--- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt
+++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt
@@ -175,6 +175,7 @@ FUNCTIONS
void getMethodVTableOffset( CORINFO_METHOD_HANDLE method, unsigned* offsetOfIndirection, unsigned* offsetAfterIndirection, bool* isRelative);
bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info);
CORINFO_METHOD_HANDLE getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg);
+ CORINFO_CLASS_HANDLE getDefaultComparerClass(CORINFO_CLASS_HANDLE elemType);
CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType);
void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult);
CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand);
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs
index 7297b94279f..5c089b18756 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs
@@ -32,6 +32,14 @@ namespace Internal.IL.Stubs
}
/// <summary>
+ /// Gets the concrete type Comparer`1.Create returns or null if it's not known at compile time.
+ /// </summary>
+ public static TypeDesc GetComparerForType(TypeDesc comparand)
+ {
+ return GetComparerForType(comparand, "Comparer", "IComparable`1");
+ }
+
+ /// <summary>
/// Gets the concrete type EqualityComparer`1.Create returns or null if it's not known at compile time.
/// </summary>
public static TypeDesc GetEqualityComparerForType(TypeDesc comparand)
diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h
index 8d6df6f3557..3c1fe2d09fb 100644
--- a/src/coreclr/tools/aot/jitinterface/jitinterface.h
+++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h
@@ -24,6 +24,7 @@ struct JitInterfaceCallbacks
void (* getMethodVTableOffset)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, unsigned* offsetOfIndirection, unsigned* offsetAfterIndirection, bool* isRelative);
bool (* resolveVirtualMethod)(void * thisHandle, CorInfoExceptionClass** ppException, void* info);
void* (* getUnboxedEntry)(void * thisHandle, CorInfoExceptionClass** ppException, void* ftn, bool* requiresInstMethodTableArg);
+ void* (* getDefaultComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, void* elemType);
void* (* getDefaultEqualityComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, void* elemType);
void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, void* pResolvedToken, void* pResult);
int (* getIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, bool* pMustExpand);
@@ -338,6 +339,15 @@ public:
return temp;
}
+ virtual void* getDefaultComparerClass(
+ void* elemType)
+{
+ CorInfoExceptionClass* pException = nullptr;
+ void* temp = _callbacks->getDefaultComparerClass(_thisHandle, &pException, elemType);
+ if (pException != nullptr) throw pException;
+ return temp;
+}
+
virtual void* getDefaultEqualityComparerClass(
void* elemType)
{
diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h
index b34222a0939..4edc72533ad 100644
--- a/src/coreclr/vm/corelib.h
+++ b/src/coreclr/vm/corelib.h
@@ -1189,6 +1189,13 @@ DEFINE_CLASS(NULLABLE_EQUALITYCOMPARER, CollectionsGeneric, NullableEqualityComp
DEFINE_CLASS(GENERIC_EQUALITYCOMPARER, CollectionsGeneric, GenericEqualityComparer`1)
DEFINE_CLASS(OBJECT_EQUALITYCOMPARER, CollectionsGeneric, ObjectEqualityComparer`1)
+// Classes referenced in Comparer<T>.Default optimization
+
+DEFINE_CLASS(GENERIC_COMPARER, CollectionsGeneric, GenericComparer`1)
+DEFINE_CLASS(OBJECT_COMPARER, CollectionsGeneric, ObjectComparer`1)
+DEFINE_CLASS(ENUM_COMPARER, CollectionsGeneric, EnumComparer`1)
+DEFINE_CLASS(NULLABLE_COMPARER, CollectionsGeneric, NullableComparer`1)
+
DEFINE_CLASS(INATTRIBUTE, Interop, InAttribute)
DEFINE_CLASS_U(CompilerServices, GCHeapHash, GCHeapHashObject)
diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp
index b48fbbe43a0..c464d3cdd14 100644
--- a/src/coreclr/vm/jitinterface.cpp
+++ b/src/coreclr/vm/jitinterface.cpp
@@ -9083,6 +9083,99 @@ void CEEInfo::expandRawHandleIntrinsic(
}
/*********************************************************************/
+CORINFO_CLASS_HANDLE CEEInfo::getDefaultComparerClass(CORINFO_CLASS_HANDLE elemType)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ CORINFO_CLASS_HANDLE result = NULL;
+
+ JIT_TO_EE_TRANSITION();
+
+ result = getDefaultComparerClassHelper(elemType);
+
+ EE_TO_JIT_TRANSITION();
+
+ return result;
+}
+
+CORINFO_CLASS_HANDLE CEEInfo::getDefaultComparerClassHelper(CORINFO_CLASS_HANDLE elemType)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ TypeHandle elemTypeHnd(elemType);
+
+ // Mirrors the logic in BCL's CompareHelpers.CreateDefaultComparer
+ // And in compile.cpp's SpecializeComparer
+ //
+ // We need to find the appropriate instantiation
+ Instantiation inst(&elemTypeHnd, 1);
+
+ // If T implements IComparable<T>
+ if (elemTypeHnd.CanCastTo(TypeHandle(CoreLibBinder::GetClass(CLASS__ICOMPARABLEGENERIC)).Instantiate(inst)))
+ {
+ TypeHandle resultTh = ((TypeHandle)CoreLibBinder::GetClass(CLASS__GENERIC_COMPARER)).Instantiate(inst);
+ return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable());
+ }
+
+ // Nullable<T>
+ if (Nullable::IsNullableType(elemTypeHnd))
+ {
+ Instantiation nullableInst = elemTypeHnd.AsMethodTable()->GetInstantiation();
+ TypeHandle iequatable = TypeHandle(CoreLibBinder::GetClass(CLASS__IEQUATABLEGENERIC)).Instantiate(nullableInst);
+ if (nullableInst[0].CanCastTo(iequatable))
+ {
+ TypeHandle resultTh = ((TypeHandle)CoreLibBinder::GetClass(CLASS__NULLABLE_COMPARER)).Instantiate(nullableInst);
+ return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable());
+ }
+ }
+
+ // We need to special case the Enum comparers based on their underlying type to avoid boxing
+ if (elemTypeHnd.IsEnum())
+ {
+ MethodTable* targetClass = NULL;
+ CorElementType normType = elemTypeHnd.GetVerifierCorElementType();
+
+ switch(normType)
+ {
+ case ELEMENT_TYPE_I1:
+ case ELEMENT_TYPE_I2:
+ case ELEMENT_TYPE_U1:
+ case ELEMENT_TYPE_U2:
+ case ELEMENT_TYPE_I4:
+ case ELEMENT_TYPE_U4:
+ case ELEMENT_TYPE_I8:
+ case ELEMENT_TYPE_U8:
+ {
+ targetClass = CoreLibBinder::GetClass(CLASS__ENUM_COMPARER);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (targetClass != NULL)
+ {
+ TypeHandle resultTh = ((TypeHandle)targetClass->GetCanonicalMethodTable()).Instantiate(inst);
+ return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable());
+ }
+ }
+
+ // Default case
+ TypeHandle resultTh = ((TypeHandle)CoreLibBinder::GetClass(CLASS__OBJECT_COMPARER)).Instantiate(inst);
+
+ return CORINFO_CLASS_HANDLE(resultTh.GetMethodTable());
+}
+
+/*********************************************************************/
CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType)
{
CONTRACTL {
@@ -9120,7 +9213,10 @@ CORINFO_CLASS_HANDLE CEEInfo::getDefaultEqualityComparerClassHelper(CORINFO_CLAS
return CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__BYTE_EQUALITYCOMPARER));
}
- // Else we'll need to find the appropriate instantation
+ // Mirrors the logic in BCL's CompareHelpers.CreateDefaultComparer
+ // And in compile.cpp's SpecializeComparer
+ //
+ // We need to find the appropriate instantiation
Instantiation inst(&elemTypeHnd, 1);
// If T implements IEquatable<T>
diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h
index 0713b1354a9..bed91204d36 100644
--- a/src/coreclr/vm/jitinterface.h
+++ b/src/coreclr/vm/jitinterface.h
@@ -452,6 +452,10 @@ public:
bool resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info);
+ CORINFO_CLASS_HANDLE getDefaultComparerClassHelper(
+ CORINFO_CLASS_HANDLE elemType
+ );
+
CORINFO_CLASS_HANDLE getDefaultEqualityComparerClassHelper(
CORINFO_CLASS_HANDLE elemType
);
diff --git a/src/coreclr/zap/zapinfo.cpp b/src/coreclr/zap/zapinfo.cpp
index d49fe508fe8..afa68c6f3e8 100644
--- a/src/coreclr/zap/zapinfo.cpp
+++ b/src/coreclr/zap/zapinfo.cpp
@@ -4069,6 +4069,12 @@ CORINFO_METHOD_HANDLE ZapInfo::getUnboxedEntry(
return m_pEEJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
}
+CORINFO_CLASS_HANDLE ZapInfo::getDefaultComparerClass(
+ CORINFO_CLASS_HANDLE elemType)
+{
+ return m_pEEJitInfo->getDefaultComparerClass(elemType);
+}
+
CORINFO_CLASS_HANDLE ZapInfo::getDefaultEqualityComparerClass(
CORINFO_CLASS_HANDLE elemType)
{
diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs
index f022ee27b1b..c21928a7381 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs
@@ -55,6 +55,7 @@ namespace System.Collections.Generic
// Needs to be public to support binary serialization compatibility
public sealed partial class GenericComparer<T> : Comparer<T> where T : IComparable<T>
{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int Compare(T? x, T? y)
{
if (x != null)
diff --git a/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.cs b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.cs
new file mode 100644
index 00000000000..36dfb4418fa
--- /dev/null
+++ b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.cs
@@ -0,0 +1,244 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+class Program
+{
+ private static int s_ReturnCode = 100;
+
+ private static void AssertEquals<T>(T expected, T actual, [CallerLineNumber] int line = 0)
+ {
+ if (!expected.Equals(actual))
+ {
+ Console.WriteLine($"{expected} != {actual}, L{line}");
+ s_ReturnCode++;
+ }
+ }
+
+ private static void Compare_Boolean(Boolean a, Boolean b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Boolean>.Default.Compare(a, b));
+
+ private static void Compare_Byte(Byte a, Byte b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Byte>.Default.Compare(a, b));
+
+ private static void Compare_SByte(SByte a, SByte b) =>
+ AssertEquals(a.CompareTo(b), Comparer<SByte>.Default.Compare(a, b));
+
+ private static void Compare_Char(Char a, Char b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Char>.Default.Compare(a, b));
+
+ private static void Compare_UInt16(UInt16 a, UInt16 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<UInt16>.Default.Compare(a, b));
+
+ private static void Compare_Int16(Int16 a, Int16 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Int16>.Default.Compare(a, b));
+
+ private static void Compare_UInt32(UInt32 a, UInt32 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<UInt32>.Default.Compare(a, b));
+
+ private static void Compare_Int32(Int32 a, Int32 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Int32>.Default.Compare(a, b));
+
+ private static void Compare_Int64(Int64 a, Int64 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Int64>.Default.Compare(a, b));
+
+ private static void Compare_UInt64(UInt64 a, UInt64 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<UInt64>.Default.Compare(a, b));
+
+ private static void Compare_IntPtr(IntPtr a, IntPtr b) =>
+ AssertEquals(a.CompareTo(b), Comparer<IntPtr>.Default.Compare(a, b));
+
+ private static void Compare_UIntPtr(UIntPtr a, UIntPtr b) =>
+ AssertEquals(a.CompareTo(b), Comparer<UIntPtr>.Default.Compare(a, b));
+
+ private static void Compare_nint(nint a, nint b) =>
+ AssertEquals(a.CompareTo(b), Comparer<nint>.Default.Compare(a, b));
+
+ private static void Compare_nuint(nuint a, nuint b) =>
+ AssertEquals(a.CompareTo(b), Comparer<nuint>.Default.Compare(a, b));
+
+ private static void Compare_Enum_Int32(MethodImplOptions a, MethodImplOptions b) =>
+ AssertEquals(a.CompareTo(b), Comparer<MethodImplOptions>.Default.Compare(a, b));
+
+ private static void Compare_Enum_Byte(Enum_byte a, Enum_byte b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Enum_byte>.Default.Compare(a, b));
+
+ private static void Compare_String(String a, String b) =>
+ AssertEquals(a.CompareTo(b), Comparer<String>.Default.Compare(a, b));
+
+ private static void Compare_DateTime(DateTime a, DateTime b) =>
+ AssertEquals(a.CompareTo(b), Comparer<DateTime>.Default.Compare(a, b));
+
+ private static void Compare_Struct1(Struct1 a, Struct1 b) =>
+ AssertEquals(a.CompareTo(b), Comparer<Struct1>.Default.Compare(a, b));
+
+ private static void Compare_Int32_Nullable(long? a, long? b)
+ {
+ int actual = Comparer<long?>.Default.Compare(a, b);
+ int expected = 0;
+ if (a.HasValue)
+ expected = b.HasValue ? a.Value.CompareTo(b.Value) : 1;
+ else
+ expected = b.HasValue ? -1 : 0;
+ AssertEquals(expected, actual);
+ }
+
+ public static int Main(string[] args)
+ {
+ long[] values = Enumerable.Range(1000, 2000)
+ .Select(i => (long)i)
+ .Concat(new[]
+ {
+ short.MinValue, short.MinValue + 1, short.MaxValue - 1, short.MaxValue, short.MaxValue + 1,
+ int.MinValue, int.MinValue + 1, int.MaxValue, int.MaxValue - 1,
+ long.MinValue, long.MinValue + 1, long.MaxValue, long.MaxValue - 1,
+ })
+ .ToArray();
+
+ for (var i = 0; i < values.Length; i++)
+ {
+ for (int j = 0; j < values.Length; j++)
+ {
+ long a = values[i];
+ long b = values[j];
+
+ var boolA = Unsafe.As<long, bool>(ref a);
+ var boolB = Unsafe.As<long, bool>(ref b);
+ Compare_Boolean(boolA, boolB);
+
+ var byteA = Unsafe.As<long, byte>(ref a);
+ var byteB = Unsafe.As<long, byte>(ref b);
+ Compare_Byte(byteA, byteB);
+
+ var sbyteA = Unsafe.As<long, sbyte>(ref a);
+ var sbyteB = Unsafe.As<long, sbyte>(ref b);
+ Compare_SByte(sbyteA, sbyteB);
+
+ var shortA = Unsafe.As<long, short>(ref a);
+ var shortB = Unsafe.As<long, short>(ref b);
+ Compare_Int16(shortA, shortB);
+
+ var ushortA = Unsafe.As<long, ushort>(ref a);
+ var ushortB = Unsafe.As<long, ushort>(ref b);
+ Compare_UInt16(ushortA, ushortB);
+
+ var charA = Unsafe.As<long, char>(ref a);
+ var charB = Unsafe.As<long, char>(ref b);
+ Compare_Char(charA, charB);
+
+ var intA = Unsafe.As<long, int>(ref a);
+ var intB = Unsafe.As<long, int>(ref b);
+ Compare_Int32(intA, intB);
+
+ var uintA = Unsafe.As<long, uint>(ref a);
+ var uintB = Unsafe.As<long, uint>(ref b);
+ Compare_UInt32(uintA, uintB);
+
+ var longA = Unsafe.As<long, long>(ref a);
+ var longB = Unsafe.As<long, long>(ref b);
+ Compare_Int64(longA, longB);
+
+ var ulongA = Unsafe.As<long, ulong>(ref a);
+ var ulongB = Unsafe.As<long, ulong>(ref b);
+ Compare_UInt64(ulongA, ulongB);
+
+ var intPtrA = Unsafe.As<long, IntPtr>(ref a);
+ var intPtrB = Unsafe.As<long, IntPtr>(ref b);
+ Compare_IntPtr(intPtrA, intPtrB);
+
+ var uintPtrA = Unsafe.As<long, UIntPtr>(ref a);
+ var uintPtrB = Unsafe.As<long, UIntPtr>(ref b);
+ Compare_UIntPtr(uintPtrA, uintPtrB);
+
+ var nintA = Unsafe.As<long, nint>(ref a);
+ var nintB = Unsafe.As<long, nint>(ref b);
+ Compare_nint(nintA, nintB);
+
+ var nuintA = Unsafe.As<long, nuint>(ref a);
+ var nuintB = Unsafe.As<long, nuint>(ref b);
+ Compare_nuint(nuintA, nuintB);
+
+ var enumIntA = Unsafe.As<long, MethodImplOptions>(ref a);
+ var enumIntB = Unsafe.As<long, MethodImplOptions>(ref b);
+ Compare_Enum_Int32(enumIntA, enumIntB);
+
+ var enumByteA = Unsafe.As<long, Enum_byte>(ref a);
+ var enumByteB = Unsafe.As<long, Enum_byte>(ref b);
+ Compare_Enum_Byte(enumByteA, enumByteB);
+
+ var structA = new Struct1 {a = a, b = b};
+ var structB = new Struct1 {a = b, b = a};
+ Compare_Struct1(structA, structB);
+
+ Compare_DateTime(
+ new DateTime(Math.Clamp(a, DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks)),
+ new DateTime(Math.Clamp(b, DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks)));
+
+ Compare_Int32_Nullable(a, b);
+ }
+ }
+
+ string[] strings = { "", "0", "00", "1", "11", "111", "привет", "Hello" };
+ foreach (var str1 in strings)
+ {
+ foreach (var str2 in strings)
+ {
+ Compare_String(str1, str2);
+ Compare_String(str2, str1);
+ }
+ }
+
+ Compare_Int32_Nullable(null, 0);
+ Compare_Int32_Nullable(0, null);
+ Compare_Int32_Nullable(null, null);
+ Compare_Int32_Nullable(null, 1);
+ Compare_Int32_Nullable(1, null);
+ Compare_Int32_Nullable(null, -1);
+ Compare_Int32_Nullable(-1, null);
+
+ GetTypeTests();
+ GetHashCodeTests();
+
+ return s_ReturnCode;
+ }
+
+ private static void GetTypeTests()
+ {
+ AssertEquals("System.Collections.Generic.GenericComparer`1[System.Int32]", Comparer<int>.Default.GetType().ToString());
+ AssertEquals("System.Collections.Generic.GenericComparer`1[System.String]", Comparer<string>.Default.GetType().ToString());
+ AssertEquals("System.Collections.Generic.GenericComparer`1[System.Guid]", Comparer<Guid>.Default.GetType().ToString());
+ AssertEquals("System.Collections.Generic.EnumComparer`1[System.Runtime.CompilerServices.MethodImplOptions]", Comparer<MethodImplOptions>.Default.GetType().ToString());
+ AssertEquals("System.Collections.Generic.NullableComparer`1[System.Byte]", Comparer<byte?>.Default.GetType().ToString());
+ AssertEquals("System.Collections.Generic.ObjectComparer`1[Struct1]", Comparer<Struct1>.Default.GetType().ToString());
+ }
+ private static int GetHashCodeTests()
+ {
+ // Just to make sure it doesn't crash
+ return Comparer<int>.Default.GetHashCode() +
+ Comparer<string>.Default.GetHashCode() +
+ Comparer<MethodImplOptions>.Default.GetHashCode() +
+ Comparer<byte?>.Default.GetHashCode() +
+ Comparer<Guid>.Default.GetHashCode() +
+ Comparer<Struct1>.Default.GetHashCode();
+ }
+}
+
+public enum Enum_byte : byte
+{
+ A,B,C,D,E
+}
+
+public struct Struct1 : IComparable
+{
+ public long a;
+ public long b;
+ public int CompareTo(object? obj)
+ {
+ return b.CompareTo(((Struct1) obj).b);
+ }
+}
diff --git a/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj
new file mode 100644
index 00000000000..d3861623ca4
--- /dev/null
+++ b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="Comparer_get_Default.cs" />
+ </ItemGroup>
+</Project>
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index 3f2f9847c7f..052e88329a1 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -963,6 +963,9 @@
<!-- Known failures for mono runtime on *all* architectures/operating systems -->
<ItemGroup Condition="'$(RuntimeFlavor)' == 'mono'" >
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/opt/Devirtualization/Comparer_get_Default/*">
+ <Issue>https://github.com/dotnet/runtime/issues/48190</Issue>
+ </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/DynamicPgo/**">
<Issue>Mono doesn't have a dynamic pgo or tiered compilation infrastructure</Issue>
</ExcludeList>