From ff25723c870e428dd7a0dc49daf13b1b908c83a5 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:37:57 +0300 Subject: [PATCH 1/9] Convert throw and thread helpers to UCO --- .../src/System/GC.CoreCLR.cs | 47 +++++---- .../src/System/Threading/Thread.CoreCLR.cs | 28 ++++-- .../src/System/Runtime/ExceptionHandling.cs | 37 +++++++ src/coreclr/vm/callhelpers.h | 98 ------------------- src/coreclr/vm/comsynchronizable.cpp | 13 ++- src/coreclr/vm/corelib.h | 10 +- src/coreclr/vm/excep.cpp | 7 +- src/coreclr/vm/exceptionhandling.cpp | 32 +++--- src/coreclr/vm/finalizerthread.cpp | 13 ++- src/coreclr/vm/metasig.h | 7 +- 10 files changed, 124 insertions(+), 168 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 2d73e6bdaf01d0..1fa8078319dab3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -312,31 +312,42 @@ public static int GetGeneration(WeakReference wo) [RequiresUnsafe] private static unsafe partial void* GetNextFinalizeableObject(ObjectHandleOnStack target); - private static unsafe uint RunFinalizers() + [UnmanagedCallersOnly] + [RequiresUnsafe] + private static unsafe uint RunFinalizers(Exception* pException) { - Thread currentThread = Thread.CurrentThread; - - uint count = 0; - while (true) + try { - object? target = null; - void* fptr = GetNextFinalizeableObject(ObjectHandleOnStack.Create(ref target)); - if (fptr == null) - break; + Thread currentThread = Thread.CurrentThread; - try - { - ((delegate*)fptr)(target!); - } - catch (Exception ex) when (ExceptionHandling.IsHandledByGlobalHandler(ex)) + uint count = 0; + while (true) { - // the handler returned "true" means the exception is now "handled" and we should continue. + object? target = null; + void* fptr = GetNextFinalizeableObject(ObjectHandleOnStack.Create(ref target)); + if (fptr == null) + break; + + try + { + ((delegate*)fptr)(target!); + } + catch (Exception ex) when (ExceptionHandling.IsHandledByGlobalHandler(ex)) + { + // the handler returned "true" means the exception is now "handled" and we should continue. + } + + currentThread.ResetFinalizerThread(); + count++; } - currentThread.ResetFinalizerThread(); - count++; + return count; + } + catch (Exception ex) + { + *pException = ex; + return default; } - return count; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCInterface_WaitForPendingFinalizers")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 2aba01144ce94a..1eb55f7b3e7622 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -112,19 +112,27 @@ private unsafe void StartCore() [RequiresUnsafe] private static unsafe partial Interop.BOOL StartInternal(ThreadHandle t, int stackSize, int priority, Interop.BOOL isThreadPool, char* pThreadName, ObjectHandleOnStack exception); - // Called from the runtime - private void StartCallback() + [UnmanagedCallersOnly] + [RequiresUnsafe] + private static unsafe void StartCallback(Thread* pThread, Exception* pException) { - StartHelper? startHelper = _startHelper; - Debug.Assert(startHelper != null); - _startHelper = null; + try + { + StartHelper? startHelper = pThread->_startHelper; + Debug.Assert(startHelper != null); + pThread->_startHelper = null; - startHelper.Run(); + startHelper.Run(); - // When this thread is about to exit, inform any subsystems that need to know. - // For external threads that have been attached to the runtime, we'll call this - // after the thread has been detached as it won't come through this path. - OnThreadExited(); + // When this thread is about to exit, inform any subsystems that need to know. + // For external threads that have been attached to the runtime, we'll call this + // after the thread has been detached as it won't come through this path. + pThread->OnThreadExited(); + } + catch (Exception ex) + { + *pException = ex; + } } // Max iterations to be done in SpinWait without switching GC modes. diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index a3d1ab789ba57e..c19e61be24a606 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -659,6 +659,19 @@ public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) #endif } +#if !NATIVEAOT + [UnmanagedCallersOnly] + [StackTraceHidden] + internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo, Exception* _) + { + object exceptionObj = *pExceptionObj; + RhThrowEx(exceptionObj, ref *pExInfo); + + Debug.Fail("unreachable"); + FallbackFailFast(RhFailFastReason.InternalError, null); + } +#endif + private const uint MaxTryRegionIdx = 0xFFFFFFFFu; #if NATIVEAOT @@ -694,6 +707,18 @@ public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo) #endif } +#if !NATIVEAOT + [UnmanagedCallersOnly] + [StackTraceHidden] + internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo, Exception* _) + { + RhRethrow(ref *pActiveExInfo, ref *pExInfo); + + Debug.Fail("unreachable"); + FallbackFailFast(RhFailFastReason.InternalError, null); + } +#endif + #if NATIVEAOT [RuntimeExport("RhRethrow")] #endif @@ -724,6 +749,18 @@ public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) #endif } +#if !NATIVEAOT + [UnmanagedCallersOnly] + [StackTraceHidden] + internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo, Exception* _) + { + RhThrowHwEx(exceptionCode, ref *pExInfo); + + Debug.Fail("unreachable"); + FallbackFailFast(RhFailFastReason.InternalError, null); + } +#endif + [StackTraceHidden] private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExInfo exInfo) { diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index 8447720a70a6f6..90f42d5a99d966 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -500,104 +500,6 @@ enum EEToManagedCallFlags /***********************************************************************/ #define ARGHOLDER_TYPE LPVOID -#define OBJECTREF_TO_ARGHOLDER(x) (LPVOID)OBJECTREFToObject(x) -#define STRINGREF_TO_ARGHOLDER(x) (LPVOID)STRINGREFToObject(x) -#define PTR_TO_ARGHOLDER(x) (LPVOID)x -#define DWORD_TO_ARGHOLDER(x) (LPVOID)(SIZE_T)x -#define BOOL_TO_ARGHOLDER(x) DWORD_TO_ARGHOLDER(!!(x)) - -#define INIT_VARIABLES(count) \ - DWORD __numArgs = count; \ - BOOL __criticalDispatchCall = FALSE; \ - -#define PREPARE_NONVIRTUAL_CALLSITE(id) \ - static PCODE s_pAddr##id = 0; \ - PCODE __pSlot = VolatileLoad(&s_pAddr##id); \ - if ( __pSlot == 0 ) \ - { \ - MethodDesc *pMeth = CoreLibBinder::GetMethod(id); \ - _ASSERTE(pMeth); \ - __pSlot = pMeth->GetMultiCallableAddrOfCode(); \ - VolatileStore(&s_pAddr##id, __pSlot); \ - } - -#define PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(pCode) \ - PCODE __pSlot = pCode; - -#define CRITICAL_CALLSITE \ - __criticalDispatchCall = TRUE; - -#define PERFORM_CALL \ - void * __retval = NULL; \ - __retval = DispatchCallSimple(__pArgs, \ - __numStackSlotsToCopy, \ - __pSlot, \ - __criticalDispatchCall); \ - -#ifdef CALLDESCR_ARGREGS - -#if defined(TARGET_X86) - -// Arguments on x86 are passed backward -#define ARGNUM_0 1 -#define ARGNUM_1 0 -#define ARGNUM_N(n) (__numArgs - (n) + 1) - -#else - -#define ARGNUM_0 0 -#define ARGNUM_1 1 -#define ARGNUM_N(n) n - -#endif - -#define PRECALL_PREP(args) \ - DWORD __numStackSlotsToCopy = (__numArgs > NUM_ARGUMENT_REGISTERS) ? (__numArgs - NUM_ARGUMENT_REGISTERS) : 0; \ - SIZE_T * __pArgs = (SIZE_T *)args; - -#define DECLARE_ARGHOLDER_ARRAY(arg, count) \ - INIT_VARIABLES(count) \ - ARGHOLDER_TYPE arg[(count <= NUM_ARGUMENT_REGISTERS ? NUM_ARGUMENT_REGISTERS : count)]; - -#else // CALLDESCR_ARGREGS - -#define ARGNUM_0 0 -#define ARGNUM_1 1 -#define ARGNUM_N(n) n - -#define PRECALL_PREP(args) \ - DWORD __numStackSlotsToCopy = (__numArgs > NUM_ARGUMENT_REGISTERS) ? __numArgs : NUM_ARGUMENT_REGISTERS; \ - SIZE_T * __pArgs = (SIZE_T *)args; - -#define DECLARE_ARGHOLDER_ARRAY(arg, count) \ - INIT_VARIABLES(count) \ - ARGHOLDER_TYPE arg[(count <= NUM_ARGUMENT_REGISTERS ? NUM_ARGUMENT_REGISTERS : count)]; - -#endif // CALLDESCR_ARGREGS - - -#define CALL_MANAGED_METHOD(ret, rettype, args) \ - PRECALL_PREP(args) \ - PERFORM_CALL \ - ret = *(rettype *)(&__retval); - -#define CALL_MANAGED_METHOD_NORET(args) \ - PRECALL_PREP(args) \ - PERFORM_CALL - -#define CALL_MANAGED_METHOD_RETREF(ret, reftype, args) \ - PRECALL_PREP(args) \ - PERFORM_CALL \ - ret = (reftype)ObjectToOBJECTREF((Object *)__retval); - -#define ARGNUM_2 ARGNUM_N(2) -#define ARGNUM_3 ARGNUM_N(3) -#define ARGNUM_4 ARGNUM_N(4) -#define ARGNUM_5 ARGNUM_N(5) -#define ARGNUM_6 ARGNUM_N(6) -#define ARGNUM_7 ARGNUM_N(7) -#define ARGNUM_8 ARGNUM_N(8) - void CallDefaultConstructor(OBJECTREF ref); diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 64b4a288db7964..3df7787561eeb4 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -31,6 +31,8 @@ #include "utilcode.h" #endif +MethodDesc* g_pThreadStartCallbackMethodDesc = nullptr; + // For the following helpers, we make no attempt to synchronize. The app developer // is responsible for managing their own race conditions. @@ -133,10 +135,13 @@ static void KickOffThread_Worker(LPVOID ptr) OBJECTREF exposedObj = GetThread()->GetExposedObjectRaw(); GCPROTECT_BEGIN(exposedObj); - PREPARE_NONVIRTUAL_CALLSITE(METHOD__THREAD__START_CALLBACK); - DECLARE_ARGHOLDER_ARRAY(args, 1); - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(exposedObj); - CALL_MANAGED_METHOD_NORET(args); + if (g_pThreadStartCallbackMethodDesc == nullptr) + { + g_pThreadStartCallbackMethodDesc = CoreLibBinder::GetMethod(METHOD__THREAD__START_CALLBACK); + } + + UnmanagedCallersOnlyCaller startCallback(METHOD__THREAD__START_CALLBACK); + startCallback.InvokeThrowing(&exposedObj); GCPROTECT_END(); } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index dcab7536023135..4ff8de82e3ac4e 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -978,7 +978,7 @@ DEFINE_FIELD(EXECUTIONCONTEXT, DEFAULT_FLOW_SUPPRESSED, DefaultFlowSu DEFINE_CLASS(DIRECTONTHREADLOCALDATA, Threading, Thread+DirectOnThreadLocalData) DEFINE_CLASS(THREAD, Threading, Thread) -DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, IM_RetVoid) +DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, SM_PtrThread_PtrException_RetVoid) DEFINE_METHOD(THREAD, POLLGC, PollGC, NoSig) DEFINE_METHOD(THREAD, ON_THREAD_EXITING, OnThreadExited, SM_PtrThread_PtrException_RetVoid) #ifdef FOR_ILLINK @@ -1031,7 +1031,7 @@ DEFINE_METHOD(VALUE_TYPE, EQUALS, Equals, DEFINE_CLASS(GC, System, GC) DEFINE_METHOD(GC, KEEP_ALIVE, KeepAlive, SM_Obj_RetVoid) -DEFINE_METHOD(GC, RUN_FINALIZERS, RunFinalizers, SM_RetUInt) +DEFINE_METHOD(GC, RUN_FINALIZERS, RunFinalizers, SM_PtrException_RetUInt) DEFINE_CLASS_U(System, WeakReference, WeakReferenceObject) DEFINE_FIELD_U(_taggedHandle, WeakReferenceObject, m_taggedHandle) @@ -1405,9 +1405,9 @@ DEFINE_FIELD_U(module, GenericHandleArgs, module) DEFINE_FIELD_U(dictionaryIndexAndSlot, GenericHandleArgs, dictionaryIndexAndSlot) DEFINE_CLASS(EH, Runtime, EH) -DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_Obj_RefExInfo_RetVoid) -DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_RefExInfo_RetVoid) -DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_RefExInfo_RefExInfo_RetVoid) +DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_PtrObj_PtrExInfo_PtrException_RetVoid) +DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_PtrExInfo_PtrException_RetVoid) +DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_PtrExInfo_PtrExInfo_PtrException_RetVoid) DEFINE_CLASS(EXCEPTIONSERVICES_INTERNALCALLS, ExceptionServices, InternalCalls) DEFINE_CLASS(STACKFRAMEITERATOR, Runtime, StackFrameIterator) diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 4aa703ba854ff9..4594fc2b2f4662 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -5646,15 +5646,12 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext) } GCPROTECT_BEGIN(exInfo.m_exception); - PREPARE_NONVIRTUAL_CALLSITE(METHOD__EH__RH_THROWHW_EX); - DECLARE_ARGHOLDER_ARRAY(args, 2); - args[ARGNUM_0] = DWORD_TO_ARGHOLDER(exceptionCode); - args[ARGNUM_1] = PTR_TO_ARGHOLDER(&exInfo); + UnmanagedCallersOnlyCaller throwHwEx(METHOD__EH__RH_THROWHW_EX); pThread->IncPreventAbort(); //Ex.RhThrowHwEx(exceptionCode, &exInfo) - CALL_MANAGED_METHOD_NORET(args) + throwHwEx.InvokeThrowing(exceptionCode, &exInfo); DispatchExSecondPass(&exInfo); diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index a1d2b1dd7fb1bb..e85a4de9ed8179 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -19,6 +19,8 @@ #include "configuration.h" extern MethodDesc* g_pEnvironmentCallEntryPointMethodDesc; +extern MethodDesc* g_pThreadStartCallbackMethodDesc; +extern MethodDesc* g_pGCRunFinalizersMethodDesc; #if defined(TARGET_X86) #define USE_CURRENT_CONTEXT_IN_FILTER @@ -1447,15 +1449,12 @@ BOOL HandleHardwareException(PAL_SEHException* ex) } GCPROTECT_BEGIN(exInfo.m_exception); - PREPARE_NONVIRTUAL_CALLSITE(METHOD__EH__RH_THROWHW_EX); - DECLARE_ARGHOLDER_ARRAY(args, 2); - args[ARGNUM_0] = DWORD_TO_ARGHOLDER(exceptionCode); - args[ARGNUM_1] = PTR_TO_ARGHOLDER(&exInfo); + UnmanagedCallersOnlyCaller throwHwEx(METHOD__EH__RH_THROWHW_EX); pThread->IncPreventAbort(); //Ex.RhThrowHwEx(exceptionCode, &exInfo) - CALL_MANAGED_METHOD_NORET(args) + throwHwEx.InvokeThrowing(exceptionCode, &exInfo); DispatchExSecondPass(&exInfo); @@ -1624,16 +1623,12 @@ VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable, CONTEXT* pE GCPROTECT_BEGIN(exInfo.m_exception); - PREPARE_NONVIRTUAL_CALLSITE(METHOD__EH__RH_THROW_EX); - DECLARE_ARGHOLDER_ARRAY(args, 2); - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(throwable); - args[ARGNUM_1] = PTR_TO_ARGHOLDER(&exInfo); + UnmanagedCallersOnlyCaller throwEx(METHOD__EH__RH_THROW_EX); pThread->IncPreventAbort(); //Ex.RhThrowEx(throwable, &exInfo) - CRITICAL_CALLSITE; - CALL_MANAGED_METHOD_NORET(args) + throwEx.InvokeThrowing(&throwable, &exInfo); DispatchExSecondPass(&exInfo); @@ -1681,16 +1676,12 @@ VOID DECLSPEC_NORETURN DispatchRethrownManagedException(CONTEXT* pExceptionConte ExInfo exInfo(pThread, pActiveExInfo->m_ptrs.ExceptionRecord, pExceptionContext, ExKind::None); GCPROTECT_BEGIN(exInfo.m_exception); - PREPARE_NONVIRTUAL_CALLSITE(METHOD__EH__RH_RETHROW); - DECLARE_ARGHOLDER_ARRAY(args, 2); - - args[ARGNUM_0] = PTR_TO_ARGHOLDER(pActiveExInfo); - args[ARGNUM_1] = PTR_TO_ARGHOLDER(&exInfo); + UnmanagedCallersOnlyCaller rethrow(METHOD__EH__RH_RETHROW); pThread->IncPreventAbort(); //Ex.RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) - CALL_MANAGED_METHOD_NORET(args) + rethrow.InvokeThrowing(pActiveExInfo, &exInfo); DispatchExSecondPass(&exInfo); GCPROTECT_END(); @@ -3977,15 +3968,16 @@ CLR_BOOL SfiNextWorker(StackFrameIterator* pThis, uint* uExCollideClauseIdx, CLR { isPropagatingToExternalNativeCode = true; -#ifdef HOST_WINDOWS MethodDesc* pMethodDesc = codeInfo.GetMethodDesc(); - if ((pMethodDesc != NULL) && pMethodDesc == g_pEnvironmentCallEntryPointMethodDesc) + if ((pMethodDesc != NULL) && + (pMethodDesc == g_pEnvironmentCallEntryPointMethodDesc || + pMethodDesc == g_pThreadStartCallbackMethodDesc || + pMethodDesc == g_pGCRunFinalizersMethodDesc)) { // Runtime-invoked UCO entrypoint calls should behave like the // internal call path and not as external-native propagation. isPropagatingToExternalNativeCode = false; } -#endif // HOST_WINDOWS } } else diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index 0126fc0e0527a6..bd9729d0feba94 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -34,6 +34,8 @@ CLREvent * FinalizerThread::hEventFinalizerToShutDown = NULL; HANDLE FinalizerThread::MHandles[kHandleCount]; +MethodDesc* g_pGCRunFinalizersMethodDesc = nullptr; + bool FinalizerThread::IsCurrentThreadFinalizer() { LIMITED_METHOD_CONTRACT; @@ -291,12 +293,13 @@ void FinalizerThread::FinalizeAllObjects() STATIC_CONTRACT_MODE_COOPERATIVE; FireEtwGCFinalizersBegin_V1(GetClrInstanceId()); + if (g_pGCRunFinalizersMethodDesc == nullptr) + { + g_pGCRunFinalizersMethodDesc = CoreLibBinder::GetMethod(METHOD__GC__RUN_FINALIZERS); + } - PREPARE_NONVIRTUAL_CALLSITE(METHOD__GC__RUN_FINALIZERS); - DECLARE_ARGHOLDER_ARRAY(args, 0); - - uint32_t count; - CALL_MANAGED_METHOD(count, uint32_t, args); + UnmanagedCallersOnlyCaller runFinalizers(METHOD__GC__RUN_FINALIZERS); + uint32_t count = runFinalizers.InvokeThrowing_Ret(); FireEtwGCFinalizersEnd_V1(count, GetClrInstanceId()); } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 464dd8c544180d..0fff402d6f433b 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -176,9 +176,9 @@ DEFINE_METASIG(SM(VoidPtr_RetVoidPtr, P(v), P(v))) DEFINE_METASIG(SM(Obj_VoidPtr_RetVoidPtr, j P(v), P(v))) DEFINE_METASIG(SM(Obj_RefBool_RetVoid, j r(F), v)) DEFINE_METASIG(SM(Obj_IntPtr_IntPtr_Int_RetIntPtr, j I I i, I)) -DEFINE_METASIG_T(SM(Obj_RefExInfo_RetVoid, j r(g(EXINFO)), v)) -DEFINE_METASIG_T(SM(UInt_RefExInfo_RetVoid, K r(g(EXINFO)), v)) -DEFINE_METASIG_T(SM(RefExInfo_RefExInfo_RetVoid, r(g(EXINFO)) r(g(EXINFO)), v)) +DEFINE_METASIG_T(SM(PtrObj_PtrExInfo_PtrException_RetVoid, P(j) P(g(EXINFO)) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(UInt_PtrExInfo_PtrException_RetVoid, K P(g(EXINFO)) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrExInfo_PtrExInfo_PtrException_RetVoid, P(g(EXINFO)) P(g(EXINFO)) P(C(EXCEPTION)), v)) #ifdef FEATURE_COMINTEROP DEFINE_METASIG(SM(Obj_IntPtr_RefIntPtr_RefBool_RetIntPtr, j I r(I) r(F), I)) #endif // FEATURE_COMINTEROP @@ -463,6 +463,7 @@ DEFINE_METASIG_T(SM(PtrChar_PtrStr_PtrException_RetVoid, P(u) P(s) P(C(EXCEPTION DEFINE_METASIG_T(SM(PtrGuid_PtrException_RetVoid, P(g(GUID)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrGuid_PtrGuid_PtrException_RetVoid, P(g(GUID)) P(g(GUID)) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrException_RetUInt, P(C(EXCEPTION)), K)) DEFINE_METASIG_T(SM(PtrLock_Int_UInt_PtrException_RetVoid, P(C(LOCK)) i K P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrThread_PtrException_RetVoid, P(C(THREAD)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrChar_PtrVoid_PtrException_RetVoid, P(u) P(v) P(C(EXCEPTION)), v)) From affd8a3f8ed5ab7f32899359aa36dcbc677852f7 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:49:54 +0300 Subject: [PATCH 2/9] Fix wasm --- src/coreclr/vm/wasm/callhelpers-reverse.cpp | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/coreclr/vm/wasm/callhelpers-reverse.cpp b/src/coreclr/vm/wasm/callhelpers-reverse.cpp index db2d9640a419b4..a871b06b05d565 100644 --- a/src/coreclr/vm/wasm/callhelpers-reverse.cpp +++ b/src/coreclr/vm/wasm/callhelpers-reverse.cpp @@ -206,6 +206,22 @@ static void Call_System_Private_CoreLib_System_GC_ConfigCallback_I32_I32_I32_I32 ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_GC_ConfigCallback_I32_I32_I32_I32_I64_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_GC_ConfigCallback_I32_I32_I32_I32_I64_RetVoid); } +static MethodDesc* MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU = nullptr; +static uint32_t Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU(void * arg0) +{ + int64_t args[1] = { (int64_t)arg0 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU) + { + LookupUnmanagedCallersOnlyMethodByName("System.GC, System.Private.CoreLib", "RunFinalizers", &MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU); + } + + uint32_t result; + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU, (int8_t*)args, sizeof(args), (int8_t*)&result, (PCODE)&Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU); + return result; +} + static MethodDesc* MD_System_Private_CoreLib_System_StubHelpers_MngdRefCustomMarshaler_ConvertContentsToManaged_I32_I32_I32_I32_RetVoid = nullptr; static void Call_System_Private_CoreLib_System_StubHelpers_MngdRefCustomMarshaler_ConvertContentsToManaged_I32_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2, void * arg3) { @@ -839,6 +855,19 @@ static void Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid); } +static MethodDesc* MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid(void * arg0, void * arg1) +{ + int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.Threading.Thread, System.Private.CoreLib", "StartCallback", &MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid); +} + static MethodDesc* MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnTypeResolve_I32_I32_I32_I32_RetVoid = nullptr; static void Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnTypeResolve_I32_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2, void * arg3) { @@ -896,6 +925,45 @@ extern "C" void SystemInteropJS_ReleaseJSOwnedObjectByGCHandle(void * arg0) Call_System_Runtime_InteropServices_JavaScript_System_Runtime_InteropServices_JavaScript_JavaScriptExports_ReleaseJSOwnedObjectByGCHandle_I32_RetVoid(arg0); } +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2) +{ + int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhRethrow", &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid); +} + +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2) +{ + int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid); +} + +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid(int32_t arg0, void * arg1, void * arg2) +{ + int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowHwEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid); +} + static MethodDesc* MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_Resolve_I32_I32_I32_I32_RetVoid = nullptr; static void Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_Resolve_I32_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2, void * arg3) { @@ -1120,8 +1188,13 @@ const ReverseThunkMapEntry g_ReverseThunks[] = { 2195947930, "ResolveUnmanagedDll#3:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDll_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDll_I32_I32_I32_RetI32 } }, { 2050198231, "ResolveUnmanagedDllUsingEvent#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDllUsingEvent_I32_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDllUsingEvent_I32_I32_I32_I32_RetI32 } }, { 2533042349, "ResolveUsingEvent#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUsingEvent_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUsingEvent_I32_I32_I32_I32_RetVoid } }, + { 250076282, "RhRethrow#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid } }, + { 24698192, "RhThrowEx#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid } }, + { 3137897039, "RhThrowHwEx#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid } }, + { 4129317514, "RunFinalizers#1:System.Private.CoreLib:System:GC", { &MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU, (void*)&Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU } }, { 1963568864, "Setup#4:System.Private.CoreLib:System:AppContext", { &MD_System_Private_CoreLib_System_AppContext_Setup_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_AppContext_Setup_I32_I32_I32_I32_RetVoid } }, { 1343309100, "StartAssemblyLoad#3:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StartAssemblyLoad_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StartAssemblyLoad_I32_I32_I32_RetVoid } }, + { 2874644056, "StartCallback#2:System.Private.CoreLib:System.Threading:Thread", { &MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid } }, { 3495913109, "StopAssemblyLoad#2:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StopAssemblyLoad_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StopAssemblyLoad_I32_I32_RetVoid } }, { 167179540, "TimerHandler#0:System.Private.CoreLib:System.Threading:TimerQueue", { &MD_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid } } }; From 6218bfe7742f69b6bbd61cddae6c21831fd22856 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Wed, 8 Apr 2026 00:12:44 +0300 Subject: [PATCH 3/9] Simplify --- .../Runtime.Base/src/System/Runtime/ExceptionHandling.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index c19e61be24a606..cbaca1d36ddb64 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -666,9 +666,6 @@ internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo, Exception { object exceptionObj = *pExceptionObj; RhThrowEx(exceptionObj, ref *pExInfo); - - Debug.Fail("unreachable"); - FallbackFailFast(RhFailFastReason.InternalError, null); } #endif @@ -713,9 +710,6 @@ public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo) internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo, Exception* _) { RhRethrow(ref *pActiveExInfo, ref *pExInfo); - - Debug.Fail("unreachable"); - FallbackFailFast(RhFailFastReason.InternalError, null); } #endif @@ -755,9 +749,6 @@ public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo, Exception* _) { RhThrowHwEx(exceptionCode, ref *pExInfo); - - Debug.Fail("unreachable"); - FallbackFailFast(RhFailFastReason.InternalError, null); } #endif From 380f5e943a7d136cf96e845fd76c8a4a7af1b9ed Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Wed, 8 Apr 2026 20:47:21 +0000 Subject: [PATCH 4/9] Address CR feedback --- .../src/System/GC.CoreCLR.cs | 46 ++++++--------- .../src/System/Threading/Thread.CoreCLR.cs | 25 +++----- .../src/System/Runtime/ExceptionHandling.cs | 59 ++++++++++--------- src/coreclr/vm/callhelpers.h | 48 +++++++++++++++ src/coreclr/vm/comsynchronizable.cpp | 2 +- src/coreclr/vm/corelib.h | 10 ++-- src/coreclr/vm/excep.cpp | 2 +- src/coreclr/vm/exceptionhandling.cpp | 6 +- src/coreclr/vm/finalizerthread.cpp | 2 +- src/coreclr/vm/metasig.h | 4 ++ src/coreclr/vm/wasm/callhelpers-reverse.cpp | 54 ++++++++--------- 11 files changed, 148 insertions(+), 110 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 1fa8078319dab3..1e8c22fe0ae12a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -314,40 +314,32 @@ public static int GetGeneration(WeakReference wo) [UnmanagedCallersOnly] [RequiresUnsafe] - private static unsafe uint RunFinalizers(Exception* pException) + private static unsafe uint RunFinalizers() { - try + Thread currentThread = Thread.CurrentThread; + + uint count = 0; + while (true) { - Thread currentThread = Thread.CurrentThread; + object? target = null; + void* fptr = GetNextFinalizeableObject(ObjectHandleOnStack.Create(ref target)); + if (fptr == null) + break; - uint count = 0; - while (true) + try { - object? target = null; - void* fptr = GetNextFinalizeableObject(ObjectHandleOnStack.Create(ref target)); - if (fptr == null) - break; - - try - { - ((delegate*)fptr)(target!); - } - catch (Exception ex) when (ExceptionHandling.IsHandledByGlobalHandler(ex)) - { - // the handler returned "true" means the exception is now "handled" and we should continue. - } - - currentThread.ResetFinalizerThread(); - count++; + ((delegate*)fptr)(target!); + } + catch (Exception ex) when (ExceptionHandling.IsHandledByGlobalHandler(ex)) + { + // the handler returned "true" means the exception is now "handled" and we should continue. } - return count; - } - catch (Exception ex) - { - *pException = ex; - return default; + currentThread.ResetFinalizerThread(); + count++; } + + return count; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCInterface_WaitForPendingFinalizers")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 1eb55f7b3e7622..f739f8421ba238 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -114,25 +114,18 @@ private unsafe void StartCore() [UnmanagedCallersOnly] [RequiresUnsafe] - private static unsafe void StartCallback(Thread* pThread, Exception* pException) + private static unsafe void StartCallback(Thread* pThread) { - try - { - StartHelper? startHelper = pThread->_startHelper; - Debug.Assert(startHelper != null); - pThread->_startHelper = null; + StartHelper? startHelper = pThread->_startHelper; + Debug.Assert(startHelper != null); + pThread->_startHelper = null; - startHelper.Run(); + startHelper.Run(); - // When this thread is about to exit, inform any subsystems that need to know. - // For external threads that have been attached to the runtime, we'll call this - // after the thread has been detached as it won't come through this path. - pThread->OnThreadExited(); - } - catch (Exception ex) - { - *pException = ex; - } + // When this thread is about to exit, inform any subsystems that need to know. + // For external threads that have been attached to the runtime, we'll call this + // after the thread has been detached as it won't come through this path. + pThread->OnThreadExited(); } // Max iterations to be done in SpinWait without switching GC modes. diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index cbaca1d36ddb64..c332511ec1633b 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -580,10 +580,19 @@ internal object ThrownException // #if NATIVEAOT [RuntimeExport("RhThrowHwEx")] +#else + [UnmanagedCallersOnly] #endif [StackTraceHidden] - public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) +#if NATIVEAOT + public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) +#else + internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo) +#endif { +#if !NATIVEAOT + ref ExInfo exInfo = ref *pExInfo; +#endif #if NATIVEAOT // trigger a GC (only if gcstress) to ensure we can stackwalk at this point GCStress.TriggerGC(); @@ -659,24 +668,24 @@ public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) #endif } -#if !NATIVEAOT - [UnmanagedCallersOnly] - [StackTraceHidden] - internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo, Exception* _) - { - object exceptionObj = *pExceptionObj; - RhThrowEx(exceptionObj, ref *pExInfo); - } -#endif - private const uint MaxTryRegionIdx = 0xFFFFFFFFu; #if NATIVEAOT [RuntimeExport("RhThrowEx")] +#else + [UnmanagedCallersOnly] #endif [StackTraceHidden] +#if NATIVEAOT public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo) +#else + internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo) +#endif { +#if !NATIVEAOT + object exceptionObj = *pExceptionObj; + ref ExInfo exInfo = ref *pExInfo; +#endif #if NATIVEAOT #if TARGET_WINDOWS @@ -704,21 +713,22 @@ public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo) #endif } -#if !NATIVEAOT - [UnmanagedCallersOnly] - [StackTraceHidden] - internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo, Exception* _) - { - RhRethrow(ref *pActiveExInfo, ref *pExInfo); - } -#endif - #if NATIVEAOT [RuntimeExport("RhRethrow")] +#else + [UnmanagedCallersOnly] #endif [StackTraceHidden] +#if NATIVEAOT public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) +#else + internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo) +#endif { +#if !NATIVEAOT + ref ExInfo activeExInfo = ref *pActiveExInfo; + ref ExInfo exInfo = ref *pExInfo; +#endif #if NATIVEAOT #if TARGET_WINDOWS @@ -743,15 +753,6 @@ public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) #endif } -#if !NATIVEAOT - [UnmanagedCallersOnly] - [StackTraceHidden] - internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo, Exception* _) - { - RhThrowHwEx(exceptionCode, ref *pExInfo); - } -#endif - [StackTraceHidden] private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExInfo exInfo) { diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index 90f42d5a99d966..d853823023a073 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -644,6 +644,54 @@ class UnmanagedCallersOnlyCaller final return ret; } + + template + void InvokeDirect(Args... args) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + _ASSERTE(_pMD->GetModule()->IsSystem()); + + OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); + + GCX_PREEMP(); + + PCODE methodEntry = _pMD->GetSingleCallableAddrOfCodeForUnmanagedCallersOnly(); + _ASSERTE(methodEntry != (PCODE)NULL); + + auto fptr = reinterpret_cast(methodEntry); + fptr(args...); + } + + template + Ret InvokeDirect_Ret(Args... args) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + _ASSERTE(_pMD->GetModule()->IsSystem()); + + OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); + + GCX_PREEMP(); + + PCODE methodEntry = _pMD->GetSingleCallableAddrOfCodeForUnmanagedCallersOnly(); + _ASSERTE(methodEntry != (PCODE)NULL); + + auto fptr = reinterpret_cast(methodEntry); + return fptr(args...); + } }; #endif //!DACCESS_COMPILE diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 3df7787561eeb4..e94a7132489660 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -141,7 +141,7 @@ static void KickOffThread_Worker(LPVOID ptr) } UnmanagedCallersOnlyCaller startCallback(METHOD__THREAD__START_CALLBACK); - startCallback.InvokeThrowing(&exposedObj); + startCallback.InvokeDirect(&exposedObj); GCPROTECT_END(); } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 4ff8de82e3ac4e..f75fdcce0c832d 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -978,7 +978,7 @@ DEFINE_FIELD(EXECUTIONCONTEXT, DEFAULT_FLOW_SUPPRESSED, DefaultFlowSu DEFINE_CLASS(DIRECTONTHREADLOCALDATA, Threading, Thread+DirectOnThreadLocalData) DEFINE_CLASS(THREAD, Threading, Thread) -DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, SM_PtrThread_PtrException_RetVoid) +DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, SM_PtrThread_RetVoid) DEFINE_METHOD(THREAD, POLLGC, PollGC, NoSig) DEFINE_METHOD(THREAD, ON_THREAD_EXITING, OnThreadExited, SM_PtrThread_PtrException_RetVoid) #ifdef FOR_ILLINK @@ -1031,7 +1031,7 @@ DEFINE_METHOD(VALUE_TYPE, EQUALS, Equals, DEFINE_CLASS(GC, System, GC) DEFINE_METHOD(GC, KEEP_ALIVE, KeepAlive, SM_Obj_RetVoid) -DEFINE_METHOD(GC, RUN_FINALIZERS, RunFinalizers, SM_PtrException_RetUInt) +DEFINE_METHOD(GC, RUN_FINALIZERS, RunFinalizers, SM_RetUInt) DEFINE_CLASS_U(System, WeakReference, WeakReferenceObject) DEFINE_FIELD_U(_taggedHandle, WeakReferenceObject, m_taggedHandle) @@ -1405,9 +1405,9 @@ DEFINE_FIELD_U(module, GenericHandleArgs, module) DEFINE_FIELD_U(dictionaryIndexAndSlot, GenericHandleArgs, dictionaryIndexAndSlot) DEFINE_CLASS(EH, Runtime, EH) -DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_PtrObj_PtrExInfo_PtrException_RetVoid) -DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_PtrExInfo_PtrException_RetVoid) -DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_PtrExInfo_PtrExInfo_PtrException_RetVoid) +DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_PtrObj_PtrExInfo_RetVoid) +DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_PtrExInfo_RetVoid) +DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_PtrExInfo_PtrExInfo_RetVoid) DEFINE_CLASS(EXCEPTIONSERVICES_INTERNALCALLS, ExceptionServices, InternalCalls) DEFINE_CLASS(STACKFRAMEITERATOR, Runtime, StackFrameIterator) diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 4594fc2b2f4662..5d17c0840dc575 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -5651,7 +5651,7 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext) pThread->IncPreventAbort(); //Ex.RhThrowHwEx(exceptionCode, &exInfo) - throwHwEx.InvokeThrowing(exceptionCode, &exInfo); + throwHwEx.InvokeDirect(exceptionCode, &exInfo); DispatchExSecondPass(&exInfo); diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index e85a4de9ed8179..5b1a222ec0227d 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -1454,7 +1454,7 @@ BOOL HandleHardwareException(PAL_SEHException* ex) pThread->IncPreventAbort(); //Ex.RhThrowHwEx(exceptionCode, &exInfo) - throwHwEx.InvokeThrowing(exceptionCode, &exInfo); + throwHwEx.InvokeDirect(exceptionCode, &exInfo); DispatchExSecondPass(&exInfo); @@ -1628,7 +1628,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable, CONTEXT* pE pThread->IncPreventAbort(); //Ex.RhThrowEx(throwable, &exInfo) - throwEx.InvokeThrowing(&throwable, &exInfo); + throwEx.InvokeDirect(&throwable, &exInfo); DispatchExSecondPass(&exInfo); @@ -1681,7 +1681,7 @@ VOID DECLSPEC_NORETURN DispatchRethrownManagedException(CONTEXT* pExceptionConte pThread->IncPreventAbort(); //Ex.RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) - rethrow.InvokeThrowing(pActiveExInfo, &exInfo); + rethrow.InvokeDirect(pActiveExInfo, &exInfo); DispatchExSecondPass(&exInfo); GCPROTECT_END(); diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index bd9729d0feba94..0e36352feb1e5e 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -299,7 +299,7 @@ void FinalizerThread::FinalizeAllObjects() } UnmanagedCallersOnlyCaller runFinalizers(METHOD__GC__RUN_FINALIZERS); - uint32_t count = runFinalizers.InvokeThrowing_Ret(); + uint32_t count = runFinalizers.InvokeDirect_Ret(); FireEtwGCFinalizersEnd_V1(count, GetClrInstanceId()); } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 0fff402d6f433b..0d631bf34b4db0 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -179,6 +179,9 @@ DEFINE_METASIG(SM(Obj_IntPtr_IntPtr_Int_RetIntPtr, j I I i, I)) DEFINE_METASIG_T(SM(PtrObj_PtrExInfo_PtrException_RetVoid, P(j) P(g(EXINFO)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(UInt_PtrExInfo_PtrException_RetVoid, K P(g(EXINFO)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrExInfo_PtrExInfo_PtrException_RetVoid, P(g(EXINFO)) P(g(EXINFO)) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrObj_PtrExInfo_RetVoid, P(j) P(g(EXINFO)), v)) +DEFINE_METASIG_T(SM(UInt_PtrExInfo_RetVoid, K P(g(EXINFO)), v)) +DEFINE_METASIG_T(SM(PtrExInfo_PtrExInfo_RetVoid, P(g(EXINFO)) P(g(EXINFO)), v)) #ifdef FEATURE_COMINTEROP DEFINE_METASIG(SM(Obj_IntPtr_RefIntPtr_RefBool_RetIntPtr, j I r(I) r(F), I)) #endif // FEATURE_COMINTEROP @@ -465,6 +468,7 @@ DEFINE_METASIG_T(SM(PtrGuid_PtrException_RetVoid, P(g(GUID)) P(C(EXCEPTION)), v) DEFINE_METASIG_T(SM(PtrGuid_PtrGuid_PtrException_RetVoid, P(g(GUID)) P(g(GUID)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrException_RetUInt, P(C(EXCEPTION)), K)) DEFINE_METASIG_T(SM(PtrLock_Int_UInt_PtrException_RetVoid, P(C(LOCK)) i K P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrThread_RetVoid, P(C(THREAD)), v)) DEFINE_METASIG_T(SM(PtrThread_PtrException_RetVoid, P(C(THREAD)) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrChar_PtrVoid_PtrException_RetVoid, P(u) P(v) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrAssemblyName_PtrNativeAssemblyNameParts_PtrException_RetVoid, P(C(ASSEMBLY_NAME)) P(g(NATIVE_ASSEMBLY_NAME_PARTS)) P(C(EXCEPTION)), v)) diff --git a/src/coreclr/vm/wasm/callhelpers-reverse.cpp b/src/coreclr/vm/wasm/callhelpers-reverse.cpp index a871b06b05d565..0d20019d2f13c1 100644 --- a/src/coreclr/vm/wasm/callhelpers-reverse.cpp +++ b/src/coreclr/vm/wasm/callhelpers-reverse.cpp @@ -207,9 +207,9 @@ static void Call_System_Private_CoreLib_System_GC_ConfigCallback_I32_I32_I32_I32 } static MethodDesc* MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU = nullptr; -static uint32_t Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU(void * arg0) +static uint32_t Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU() { - int64_t args[1] = { (int64_t)arg0 }; + int64_t args[0] = { }; // Lazy lookup of MethodDesc for the function export scenario. if (!MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU) @@ -856,9 +856,9 @@ static void Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I } static MethodDesc* MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid = nullptr; -static void Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid(void * arg0, void * arg1) +static void Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid(void * arg0) { - int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; + int64_t args[1] = { (int64_t)arg0 }; // Lazy lookup of MethodDesc for the function export scenario. if (!MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid) @@ -925,43 +925,43 @@ extern "C" void SystemInteropJS_ReleaseJSOwnedObjectByGCHandle(void * arg0) Call_System_Runtime_InteropServices_JavaScript_System_Runtime_InteropServices_JavaScript_JavaScriptExports_ReleaseJSOwnedObjectByGCHandle_I32_RetVoid(arg0); } -static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid = nullptr; -static void Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2) +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid(void * arg0, void * arg1) { - int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid) + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid) { - LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhRethrow", &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid); + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhRethrow", &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid); } - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid); + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid); } -static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid = nullptr; -static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2) +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid(void * arg0, void * arg1) { - int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid) + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid) { - LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid); + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid); } - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid); + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid); } -static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid = nullptr; -static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid(int32_t arg0, void * arg1, void * arg2) +static MethodDesc* MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid(int32_t arg0, void * arg1) { - int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; + int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid) + if (!MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid) { - LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowHwEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid); + LookupUnmanagedCallersOnlyMethodByName("System.Runtime.EH, System.Private.CoreLib", "RhThrowHwEx", &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid); } - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid); + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid); } static MethodDesc* MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_Resolve_I32_I32_I32_I32_RetVoid = nullptr; @@ -1188,13 +1188,13 @@ const ReverseThunkMapEntry g_ReverseThunks[] = { 2195947930, "ResolveUnmanagedDll#3:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDll_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDll_I32_I32_I32_RetI32 } }, { 2050198231, "ResolveUnmanagedDllUsingEvent#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDllUsingEvent_I32_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUnmanagedDllUsingEvent_I32_I32_I32_I32_RetI32 } }, { 2533042349, "ResolveUsingEvent#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUsingEvent_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_ResolveUsingEvent_I32_I32_I32_I32_RetVoid } }, - { 250076282, "RhRethrow#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_I32_RetVoid } }, - { 24698192, "RhThrowEx#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_I32_RetVoid } }, - { 3137897039, "RhThrowHwEx#3:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_I32_RetVoid } }, - { 4129317514, "RunFinalizers#1:System.Private.CoreLib:System:GC", { &MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU, (void*)&Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU } }, + { 2883735131, "RhRethrow#2:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhRethrow_I32_I32_RetVoid } }, + { 3929107505, "RhThrowEx#2:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowEx_I32_I32_RetVoid } }, + { 504238190, "RhThrowHwEx#2:System.Private.CoreLib:System.Runtime:EH", { &MD_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_EH_RhThrowHwEx_I32_I32_RetVoid } }, + { 4273572779, "RunFinalizers#0:System.Private.CoreLib:System:GC", { &MD_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU, (void*)&Call_System_Private_CoreLib_System_GC_RunFinalizers_I32_RetU } }, { 1963568864, "Setup#4:System.Private.CoreLib:System:AppContext", { &MD_System_Private_CoreLib_System_AppContext_Setup_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_AppContext_Setup_I32_I32_I32_I32_RetVoid } }, { 1343309100, "StartAssemblyLoad#3:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StartAssemblyLoad_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StartAssemblyLoad_I32_I32_I32_RetVoid } }, - { 2874644056, "StartCallback#2:System.Private.CoreLib:System.Threading:Thread", { &MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid } }, + { 3372184251, "StartCallback#1:System.Private.CoreLib:System.Threading:Thread", { &MD_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_Thread_StartCallback_I32_I32_RetVoid } }, { 3495913109, "StopAssemblyLoad#2:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StopAssemblyLoad_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_StopAssemblyLoad_I32_I32_RetVoid } }, { 167179540, "TimerHandler#0:System.Private.CoreLib:System.Threading:TimerQueue", { &MD_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid } } }; From e3e571af125d2a11595fafd2966e8a0655a0397f Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Wed, 8 Apr 2026 23:50:41 +0300 Subject: [PATCH 5/9] Apply suggestions from code review Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../Runtime.Base/src/System/Runtime/ExceptionHandling.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index c332511ec1633b..0b3c3aae0f5431 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -581,7 +581,7 @@ internal object ThrownException #if NATIVEAOT [RuntimeExport("RhThrowHwEx")] #else - [UnmanagedCallersOnly] + [UnmanagedCallersOnly] #endif [StackTraceHidden] #if NATIVEAOT @@ -716,7 +716,7 @@ internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo) #if NATIVEAOT [RuntimeExport("RhRethrow")] #else - [UnmanagedCallersOnly] + [UnmanagedCallersOnly] #endif [StackTraceHidden] #if NATIVEAOT From 06da0e11a70dcb2fbbac4f9985edc57cecd276c6 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:15:49 +0300 Subject: [PATCH 6/9] Styling --- .../src/System/Runtime/ExceptionHandling.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index 0b3c3aae0f5431..7437626370c9f2 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -578,20 +578,17 @@ internal object ThrownException // // Called by RhpThrowHwEx // + [StackTraceHidden] #if NATIVEAOT [RuntimeExport("RhThrowHwEx")] + public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) #else [UnmanagedCallersOnly] -#endif - [StackTraceHidden] -#if NATIVEAOT - public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo) -#else - internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo) + internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo) #endif { #if !NATIVEAOT - ref ExInfo exInfo = ref *pExInfo; + ref ExInfo exInfo = ref *pExInfo; #endif #if NATIVEAOT // trigger a GC (only if gcstress) to ensure we can stackwalk at this point @@ -713,21 +710,18 @@ internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo) #endif } -#if NATIVEAOT - [RuntimeExport("RhRethrow")] -#else - [UnmanagedCallersOnly] -#endif [StackTraceHidden] #if NATIVEAOT + [RuntimeExport("RhRethrow")] public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo) #else - internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo) + [UnmanagedCallersOnly] + internal static void RhRethrow(ExInfo* pActiveExInfo, ExInfo* pExInfo) #endif { #if !NATIVEAOT - ref ExInfo activeExInfo = ref *pActiveExInfo; - ref ExInfo exInfo = ref *pExInfo; + ref ExInfo activeExInfo = ref *pActiveExInfo; + ref ExInfo exInfo = ref *pExInfo; #endif #if NATIVEAOT From bb63ec6802898e6b25c9afdd3d55700966102244 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:18:23 +0300 Subject: [PATCH 7/9] . --- .../Runtime.Base/src/System/Runtime/ExceptionHandling.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index 7437626370c9f2..b1969079388f7d 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -667,15 +667,12 @@ internal static void RhThrowHwEx(uint exceptionCode, ExInfo* pExInfo) private const uint MaxTryRegionIdx = 0xFFFFFFFFu; -#if NATIVEAOT - [RuntimeExport("RhThrowEx")] -#else - [UnmanagedCallersOnly] -#endif [StackTraceHidden] #if NATIVEAOT + [RuntimeExport("RhThrowEx")] public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo) #else + [UnmanagedCallersOnly] internal static void RhThrowEx(object* pExceptionObj, ExInfo* pExInfo) #endif { From aa2eb4d2370edfb081473be914d73d064138b616 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:25:05 +0300 Subject: [PATCH 8/9] Fix argument type in startCallback invocation --- src/coreclr/vm/comsynchronizable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index e94a7132489660..ac8083579ecd0f 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -141,7 +141,7 @@ static void KickOffThread_Worker(LPVOID ptr) } UnmanagedCallersOnlyCaller startCallback(METHOD__THREAD__START_CALLBACK); - startCallback.InvokeDirect(&exposedObj); + startCallback.InvokeDirect(OBJECTREFToObject(exposedObj)); GCPROTECT_END(); } From 50a507f62143d3c167ba6ce3a50baa5dbbf29338 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:58:37 +0300 Subject: [PATCH 9/9] Apply suggestion --- src/coreclr/vm/comsynchronizable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index ac8083579ecd0f..e94a7132489660 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -141,7 +141,7 @@ static void KickOffThread_Worker(LPVOID ptr) } UnmanagedCallersOnlyCaller startCallback(METHOD__THREAD__START_CALLBACK); - startCallback.InvokeDirect(OBJECTREFToObject(exposedObj)); + startCallback.InvokeDirect(&exposedObj); GCPROTECT_END(); }