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 202a339b68025..bc67edd5c43ff 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)] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool IsInstanceOf_NoCacheLookup(void *toTypeHnd, [MarshalAs(UnmanagedType.Bool)] bool throwCastException, ObjectHandleOnStack obj); - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern object ChkCastAny_NoCacheLookup(void* toTypeHnd, object obj); + [MethodImpl(MethodImplOptions.NoInlining)] + private static object? IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj) + { + if (IsInstanceOf_NoCacheLookup(toTypeHnd, false, ObjectHandleOnStack.Create(ref obj))) + { + return obj; + } + return null; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static 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); @@ -462,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] @@ -494,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(); } diff --git a/src/coreclr/vm/JitQCallHelpers.h b/src/coreclr/vm/JitQCallHelpers.h index ff3bfa97981f3..f229bff39f9fc 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 fe9e988207e3a..9c81085e1c1f4 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 88bb4981d6572..5a37be7c30942 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 6038fbfbbcc49..71012b72649d1 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -230,10 +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); -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 +// 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); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 0833de88b58bc..81ea42b9965d0 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)