From 349f78993aa73756010d97532f9afe729155e4a0 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 21 Nov 2024 11:49:05 -0800 Subject: [PATCH 1/5] Remove 2 more casting helper method frames --- .../Runtime/CompilerServices/CastHelpers.cs | 23 ++++++++-- src/coreclr/vm/JitQCallHelpers.h | 1 + src/coreclr/vm/ecalllist.h | 2 - src/coreclr/vm/jithelpers.cpp | 45 ++++--------------- src/coreclr/vm/jitinterface.h | 3 -- src/coreclr/vm/qcallentrypoints.cpp | 1 + 6 files changed, 29 insertions(+), 46 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 202a339b680251..6a8ddae1c260b0 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -24,11 +24,26 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) throw null!; // Provide hint to the inliner that this method does not return } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern object IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj); + [LibraryImport(RuntimeHelpers.QCall)] + private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, bool throwCastException, ObjectHandleOnStack obj); - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern object ChkCastAny_NoCacheLookup(void* toTypeHnd, object obj); + [MethodImpl(MethodImplOptions.NoInlining)] + private static extern object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) + { + ObjectHandleOfStack objHandleOnStack = default; + if (IsInstanceOf_NoCacheLookup(toTypeHnd, false, ObjectHandleOnStack.Create(ref obj))) + { + return obj; + } + return null; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static extern object ChkCastAny_NoCacheLookup(void* toTypeHnd, object obj) + { + IsInstanceOf_NoCacheLookup(toTypeHnd, true, ObjectHandleOnStack.Create(ref obj)); + return obj; + } [MethodImpl(MethodImplOptions.InternalCall)] private static extern void WriteBarrier(ref object? dst, object? obj); diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index ff3bfa97981f3e..f229bff39f9fca 100644 --- a/src/coreclr/vm/JitQCallHelpers.h +++ b/src/coreclr/vm/JitQCallHelpers.h @@ -24,5 +24,6 @@ extern "C" void QCALLTYPE InitClassHelper(MethodTable* pMT); extern "C" void QCALLTYPE ThrowInvalidCastException(CORINFO_CLASS_HANDLE pTargetType, CORINFO_CLASS_HANDLE pSourceType); extern "C" void QCALLTYPE GetThreadStaticsByMethodTable(QCall::ByteRefOnStack refHandle, MethodTable* pMT, bool gcStatic); extern "C" void QCALLTYPE GetThreadStaticsByIndex(QCall::ByteRefOnStack refHandle, uint32_t staticBlockIndex, bool gcStatic); +extern "C" BOOL QCALLTYPE IsInstanceOf_NoCacheLookup(CORINFO_CLASS_HANDLE type, BOOL throwCastException, QCall::ObjectHandleOnStack objOnStack); #endif //_JITQCALLHELPERS_H diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index fe9e988207e3a5..9c81085e1c1f4d 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -263,8 +263,6 @@ FCFuncStart(gThreadPoolFuncs) FCFuncEnd() FCFuncStart(gCastHelpers) - FCFuncElement("IsInstanceOfAny_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup) - FCFuncElement("ChkCastAny_NoCacheLookup", ::ChkCastAny_NoCacheLookup) FCFuncElement("WriteBarrier", ::WriteBarrier_Helper) FCFuncEnd() diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 88bb4981d65729..5a37be7c309429 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -781,51 +781,22 @@ BOOL ObjIsInstanceOf(Object* pObject, TypeHandle toTypeHnd, BOOL throwCastExcept return ObjIsInstanceOfCore(pObject, toTypeHnd, throwCastException); } -HCIMPL2(Object*, ChkCastAny_NoCacheLookup, CORINFO_CLASS_HANDLE type, Object* obj) +extern "C" BOOL QCALLTYPE IsInstanceOf_NoCacheLookup(CORINFO_CLASS_HANDLE type, BOOL throwCastException, QCall::ObjectHandleOnStack objOnStack) { - FCALL_CONTRACT; - - // This case should be handled by frameless helper - _ASSERTE(obj != NULL); - - OBJECTREF oref = ObjectToOBJECTREF(obj); - VALIDATEOBJECTREF(oref); - - TypeHandle clsHnd(type); - - HELPER_METHOD_FRAME_BEGIN_RET_1(oref); - if (!ObjIsInstanceOfCore(OBJECTREFToObject(oref), clsHnd, TRUE)) - { - UNREACHABLE(); //ObjIsInstanceOf will throw if cast can't be done - } - HELPER_METHOD_POLL(); - HELPER_METHOD_FRAME_END(); - - return OBJECTREFToObject(oref); -} -HCIMPLEND - -HCIMPL2(Object*, IsInstanceOfAny_NoCacheLookup, CORINFO_CLASS_HANDLE type, Object* obj) -{ - FCALL_CONTRACT; + QCALL_CONTRACT; + BOOL result = FALSE; - // This case should be handled by frameless helper - _ASSERTE(obj != NULL); + BEGIN_QCALL; - OBJECTREF oref = ObjectToOBJECTREF(obj); - VALIDATEOBJECTREF(oref); + GCX_COOP(); TypeHandle clsHnd(type); + result = ObjIsInstanceOfCore(OBJECTREFToObject(objOnStack.Get()), clsHnd, throwCastException); - HELPER_METHOD_FRAME_BEGIN_RET_1(oref); - if (!ObjIsInstanceOfCore(OBJECTREFToObject(oref), clsHnd)) - oref = NULL; - HELPER_METHOD_POLL(); - HELPER_METHOD_FRAME_END(); + END_QCALL; - return OBJECTREFToObject(oref); + return result; } -HCIMPLEND //======================================================================== // diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 6038fbfbbcc499..b01ffcb6416755 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -230,9 +230,6 @@ extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref); extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref); extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref); -extern "C" FCDECL2(Object*, ChkCastAny_NoCacheLookup, CORINFO_CLASS_HANDLE type, Object* obj); -extern "C" FCDECL2(Object*, IsInstanceOfAny_NoCacheLookup, CORINFO_CLASS_HANDLE type, Object* obj); - // ARM64 JIT_WriteBarrier uses speciall ABI and thus is not callable directly // Copied write barriers must be called at a different location extern "C" FCDECL2(VOID, JIT_WriteBarrier_Callable, Object **dst, Object *ref); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 0833de88b58bc6..81ea42b9965d09 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -506,6 +506,7 @@ static const Entry s_QCall[] = DllImportEntry(GetThreadStaticsByIndex) DllImportEntry(GenericHandleWorker) DllImportEntry(ThrowInvalidCastException) + DllImportEntry(IsInstanceOf_NoCacheLookup) }; const void* QCallResolveDllImport(const char* name) From 6f1b4dbd7292d0b84745e7664e2c29390943fe13 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 22 Nov 2024 13:55:06 -0800 Subject: [PATCH 2/5] Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../src/System/Runtime/CompilerServices/CastHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 6a8ddae1c260b0..2278623062ec18 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -28,7 +28,7 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, bool throwCastException, ObjectHandleOnStack obj); [MethodImpl(MethodImplOptions.NoInlining)] - private static extern object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) + private static object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) { ObjectHandleOfStack objHandleOnStack = default; if (IsInstanceOf_NoCacheLookup(toTypeHnd, false, ObjectHandleOnStack.Create(ref obj))) From 9d93245daec4ee76a2f481a9852b4b66dcde6d60 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 22 Nov 2024 13:55:37 -0800 Subject: [PATCH 3/5] Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../src/System/Runtime/CompilerServices/CastHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 2278623062ec18..56767e5e20b86c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -25,7 +25,7 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) } [LibraryImport(RuntimeHelpers.QCall)] - private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, bool throwCastException, ObjectHandleOnStack obj); + private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, [MarshalAs(UnmanagedType.Bool)] bool throwCastException, ObjectHandleOnStack obj); [MethodImpl(MethodImplOptions.NoInlining)] private static object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) From 1ed11e5109c2720404df8ddcf3eaabc9f056a9cd Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 22 Nov 2024 13:55:45 -0800 Subject: [PATCH 4/5] Update src/coreclr/vm/jitinterface.h Co-authored-by: Theodore Tsirpanis --- src/coreclr/vm/jitinterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index b01ffcb6416755..71012b72649d1f 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -230,7 +230,7 @@ extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref); extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref); extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref); -// ARM64 JIT_WriteBarrier uses speciall ABI and thus is not callable directly +// ARM64 JIT_WriteBarrier uses special ABI and thus is not callable directly // Copied write barriers must be called at a different location extern "C" FCDECL2(VOID, JIT_WriteBarrier_Callable, Object **dst, Object *ref); From 4c29470137e35deba927c380da408876829b5379 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 6 Dec 2024 11:59:51 -0800 Subject: [PATCH 5/5] More code updates as suggested by am11 --- .../System/Runtime/CompilerServices/CastHelpers.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 56767e5e20b86c..bc67edd5c43ff3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -25,12 +25,12 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) } [LibraryImport(RuntimeHelpers.QCall)] + [return: MarshalAs(UnmanagedType.Bool)] private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, [MarshalAs(UnmanagedType.Bool)] bool throwCastException, ObjectHandleOnStack obj); [MethodImpl(MethodImplOptions.NoInlining)] private static object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) { - ObjectHandleOfStack objHandleOnStack = default; if (IsInstanceOf_NoCacheLookup(toTypeHnd, false, ObjectHandleOnStack.Create(ref obj))) { return obj; @@ -39,7 +39,7 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) } [MethodImpl(MethodImplOptions.NoInlining)] - private static extern object ChkCastAny_NoCacheLookup(void* toTypeHnd, object obj) + private static object ChkCastAny_NoCacheLookup(void* toTypeHnd, object obj) { IsInstanceOf_NoCacheLookup(toTypeHnd, true, ObjectHandleOnStack.Create(ref obj)); return obj; @@ -477,13 +477,13 @@ private static void StelemRef_Helper_NoCacheLookup(ref object? element, void* el { Debug.Assert(obj != null); - obj = IsInstanceOfAny_NoCacheLookup(elementType, obj); - if (obj == null) + object? obj2 = IsInstanceOfAny_NoCacheLookup(elementType, obj); + if (obj2 == null) { ThrowArrayMismatchException(); } - WriteBarrier(ref element, obj); + WriteBarrier(ref element, obj2); } [DebuggerHidden] @@ -509,8 +509,7 @@ private static unsafe void ArrayTypeCheck_Helper(object obj, void* elementType) { Debug.Assert(obj != null); - obj = IsInstanceOfAny_NoCacheLookup(elementType, obj); - if (obj == null) + if (IsInstanceOfAny_NoCacheLookup(elementType, obj) == null) { ThrowArrayMismatchException(); }