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 0c640dd1c2f0a4..dbc3d064acc7a0 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 @@ -462,5 +462,37 @@ private static void StelemRef_Helper_NoCacheLookup(ref object? element, void* el WriteBarrier(ref element, obj); } + +#if FEATURE_ARRAYSTUB_AS_IL + [DebuggerHidden] + private static unsafe void ArrayTypeCheck(object obj, Array array) + { + Debug.Assert(obj != null); + + void* elementType = RuntimeHelpers.GetMethodTable(array)->ElementType; + Debug.Assert(elementType != RuntimeHelpers.GetMethodTable(obj)); // Should be handled by caller + + CastResult result = CastCache.TryGet(s_table!, (nuint)RuntimeHelpers.GetMethodTable(obj), (nuint)elementType); + if (result == CastResult.CanCast) + { + return; + } + + ArrayTypeCheck_Helper(obj, elementType); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.NoInlining)] + private static unsafe void ArrayTypeCheck_Helper(object obj, void* elementType) + { + Debug.Assert(obj != null); + + obj = IsInstanceOfAny_NoCacheLookup(elementType, obj); + if (obj == null) + { + ThrowArrayMismatchException(); + } + } +#endif } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index e772613855c767..cd96be08049005 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1616,11 +1616,6 @@ internal static unsafe void LayoutDestroyNativeInternal(object obj, byte* pNativ [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IntPtr GetStubContext(); -#if FEATURE_ARRAYSTUB_AS_IL - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ArrayTypeCheck(object o, object[] arr); -#endif - #if FEATURE_MULTICASTSTUB_AS_IL [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void MulticastDebuggerTraceHelper(object o, int count); diff --git a/src/coreclr/vm/array.cpp b/src/coreclr/vm/array.cpp index bb05b85f4f10ce..806db9309f0fb3 100644 --- a/src/coreclr/vm/array.cpp +++ b/src/coreclr/vm/array.cpp @@ -706,7 +706,7 @@ class ArrayOpLinker : public ILStubLinker // Call type check helper m_pCode->EmitLDARG(rank); m_pCode->EmitLoadThis(); - m_pCode->EmitCALL(METHOD__STUBHELPERS__ARRAY_TYPE_CHECK,2,0); + m_pCode->EmitCALL(METHOD__CASTHELPERS__ARRAYTYPECHECK,2,0); m_pCode->EmitLabel(pTypeCheckOK); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index df42e52eab9527..6db24bedadb969 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -939,10 +939,6 @@ DEFINE_METHOD(STUBHELPERS, PROFILER_BEGIN_TRANSITION_CALLBACK, Profiler DEFINE_METHOD(STUBHELPERS, PROFILER_END_TRANSITION_CALLBACK, ProfilerEndTransitionCallback, SM_IntPtr_IntPtr_RetVoid) #endif -#ifdef FEATURE_ARRAYSTUB_AS_IL -DEFINE_METHOD(STUBHELPERS, ARRAY_TYPE_CHECK, ArrayTypeCheck, SM_Obj_ArrObject_RetVoid) -#endif - #ifdef FEATURE_MULTICASTSTUB_AS_IL DEFINE_METHOD(STUBHELPERS, MULTICAST_DEBUGGER_TRACE_HELPER, MulticastDebuggerTraceHelper, SM_Obj_Int_RetVoid) #endif @@ -1169,6 +1165,9 @@ DEFINE_METHOD(CASTHELPERS, CHKCASTCLASSSPECIAL, ChkCastClassSpecial, SM_Ptr DEFINE_METHOD(CASTHELPERS, UNBOX, Unbox, SM_PtrVoid_Obj_RetRefByte) DEFINE_METHOD(CASTHELPERS, STELEMREF, StelemRef, SM_ArrObject_IntPtr_Obj_RetVoid) DEFINE_METHOD(CASTHELPERS, LDELEMAREF, LdelemaRef, SM_ArrObject_IntPtr_PtrVoid_RetRefObj) +#ifdef FEATURE_ARRAYSTUB_AS_IL +DEFINE_METHOD(CASTHELPERS, ARRAYTYPECHECK, ArrayTypeCheck, SM_Obj_Array_RetVoid) +#endif #ifdef FEATURE_EH_FUNCLETS DEFINE_CLASS(EH, Runtime, EH) diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 7e00292a146b17..4a9f2355f395c2 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -479,9 +479,6 @@ FCFuncStart(gStubHelperFuncs) FCFuncElement("ValidateByref", StubHelpers::ValidateByref) FCFuncElement("LogPinnedArgument", StubHelpers::LogPinnedArgument) FCFuncElement("GetStubContext", StubHelpers::GetStubContext) -#ifdef FEATURE_ARRAYSTUB_AS_IL - FCFuncElement("ArrayTypeCheck", StubHelpers::ArrayTypeCheck) -#endif //FEATURE_ARRAYSTUB_AS_IL #ifdef FEATURE_MULTICASTSTUB_AS_IL FCFuncElement("MulticastDebuggerTraceHelper", StubHelpers::MulticastDebuggerTraceHelper) #endif //FEATURE_MULTICASTSTUB_AS_IL diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 35e6472b4b8daf..b7f033fbbf54f3 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -211,7 +211,7 @@ DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_UShrt_IntPtr_RetVoid, I I I H I, v)) DEFINE_METASIG(SM(IntPtr_Int_IntPtr_RetIntPtr, I i I, I)) DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Bool_IntPtr_RetVoid, I I i F I, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_Obj_RetVoid, I I j, v)) -DEFINE_METASIG(SM(Obj_ArrObject_RetVoid, j a(j), v)) +DEFINE_METASIG_T(SM(Obj_Array_RetVoid, j C(ARRAY), v)) DEFINE_METASIG(SM(Obj_IntPtr_Obj_RetVoid, j I j, v)) DEFINE_METASIG(SM(RetUIntPtr, _, U)) DEFINE_METASIG(SM(RetIntPtr, _, I)) diff --git a/src/coreclr/vm/stubhelpers.cpp b/src/coreclr/vm/stubhelpers.cpp index c5d2666826cd43..187c86f53a375f 100644 --- a/src/coreclr/vm/stubhelpers.cpp +++ b/src/coreclr/vm/stubhelpers.cpp @@ -808,32 +808,6 @@ FCIMPL1(DWORD, StubHelpers::CalcVaListSize, VARARGS *varargs) } FCIMPLEND -#ifdef FEATURE_ARRAYSTUB_AS_IL -NOINLINE static void ArrayTypeCheckSlow(Object* element, PtrArray* arr) -{ - FC_INNER_PROLOG(StubHelpers::ArrayTypeCheck); - HELPER_METHOD_FRAME_BEGIN_ATTRIB(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2); - - if (!ObjIsInstanceOf(element, arr->GetArrayElementTypeHandle())) - COMPlusThrow(kArrayTypeMismatchException); - - HELPER_METHOD_FRAME_END(); - - FC_INNER_EPILOG(); -} - -FCIMPL2(void, StubHelpers::ArrayTypeCheck, Object* element, PtrArray* arr) -{ - FCALL_CONTRACT; - - if (ObjIsInstanceOfCached(element, arr->GetArrayElementTypeHandle()) == TypeHandle::CanCast) - return; - - FC_INNER_RETURN_VOID(ArrayTypeCheckSlow(element, arr)); -} -FCIMPLEND -#endif // FEATURE_ARRAYSTUB_AS_IL - #ifdef FEATURE_MULTICASTSTUB_AS_IL FCIMPL2(void, StubHelpers::MulticastDebuggerTraceHelper, Object* element, INT32 count) { diff --git a/src/coreclr/vm/stubhelpers.h b/src/coreclr/vm/stubhelpers.h index 9f8c2a173b9147..16b3f9230fcd78 100644 --- a/src/coreclr/vm/stubhelpers.h +++ b/src/coreclr/vm/stubhelpers.h @@ -75,10 +75,6 @@ class StubHelpers static FCDECL2(void, ProfilerEndTransitionCallback, MethodDesc* pRealMD, Thread* pThread); #endif -#ifdef FEATURE_ARRAYSTUB_AS_IL - static FCDECL2(void, ArrayTypeCheck, Object*, PtrArray*); -#endif - #ifdef FEATURE_MULTICASTSTUB_AS_IL static FCDECL2(void, MulticastDebuggerTraceHelper, Object*, INT32); #endif