Skip to content

Commit

Permalink
Remove 2 more casting helper method frames (#110064)
Browse files Browse the repository at this point in the history
* Remove 2 more casting helper method frames

* Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs

Co-authored-by: Adeel Mujahid <[email protected]>

* Update src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs

Co-authored-by: Adeel Mujahid <[email protected]>

* Update src/coreclr/vm/jitinterface.h

Co-authored-by: Theodore Tsirpanis <[email protected]>

* More code updates as suggested by am11

---------

Co-authored-by: Adeel Mujahid <[email protected]>
Co-authored-by: Theodore Tsirpanis <[email protected]>
  • Loading branch information
3 people authored Dec 6, 2024
1 parent 43d1838 commit 2d81cbb
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -464,13 +479,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]
Expand All @@ -496,8 +511,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();
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/JitQCallHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 0 additions & 2 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ FCFuncStart(gThreadPoolFuncs)
FCFuncEnd()

FCFuncStart(gCastHelpers)
FCFuncElement("IsInstanceOfAny_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup)
FCFuncElement("ChkCastAny_NoCacheLookup", ::ChkCastAny_NoCacheLookup)
FCFuncElement("WriteBarrier", ::WriteBarrier_Helper)
FCFuncEnd()

Expand Down
45 changes: 8 additions & 37 deletions src/coreclr/vm/jithelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

//========================================================================
//
Expand Down
5 changes: 1 addition & 4 deletions src/coreclr/vm/jitinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ static const Entry s_QCall[] =
DllImportEntry(GetThreadStaticsByIndex)
DllImportEntry(GenericHandleWorker)
DllImportEntry(ThrowInvalidCastException)
DllImportEntry(IsInstanceOf_NoCacheLookup)
};

const void* QCallResolveDllImport(const char* name)
Expand Down

0 comments on commit 2d81cbb

Please sign in to comment.