From fbd3628f179571e8039d0cb0e8f8773819fd45de Mon Sep 17 00:00:00 2001 From: DongHeon Jung Date: Wed, 29 Apr 2026 11:23:06 +0900 Subject: [PATCH 1/3] [clr-interp] Use struct parameter for InvokeUnmanagedCalliWithTransition On ARM32, bundling arguments in a struct forces register passing, ensuring the SP value saved by SAVE_THE_LOWEST_SP matches what stack walking reports. --- src/coreclr/vm/interpexec.cpp | 13 ++++++++----- src/coreclr/vm/interpexec.h | 10 ++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index d89ae68d123d6f..c3d1b5ead7fefb 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -287,7 +287,7 @@ void InvokeUnmanagedMethodWithTransition(UnmanagedMethodWithTransitionParam *pPa } NOINLINE -void InvokeUnmanagedCalliWithTransition(PCODE ftn, void *cookie, int8_t *stack, InterpMethodContextFrame *pFrame, int8_t *pArgs, int8_t *pRet) +void InvokeUnmanagedCalliWithTransition(UnmanagedCalliWithTransiationParam *pParam) { CONTRACTL { @@ -298,10 +298,12 @@ void InvokeUnmanagedCalliWithTransition(PCODE ftn, void *cookie, int8_t *stack, } CONTRACTL_END + InterpMethodContextFrame *pFrame = pParam->pFrame; + InlinedCallFrame inlinedCallFrame; inlinedCallFrame.m_pCallerReturnAddress = (TADDR)pFrame->ip; inlinedCallFrame.m_pCallSiteSP = pFrame; - inlinedCallFrame.m_pCalleeSavedFP = (TADDR)stack; + inlinedCallFrame.m_pCalleeSavedFP = (TADDR)pParam->stack; inlinedCallFrame.m_pThread = GetThread(); inlinedCallFrame.m_Datum = NULL; inlinedCallFrame.Push(); @@ -310,10 +312,10 @@ void InvokeUnmanagedCalliWithTransition(PCODE ftn, void *cookie, int8_t *stack, #ifdef PROFILING_SUPPORTED if (CORProfilerTrackTransitions() && !pFrame->startIp->Method->methodHnd->IsILStub()) { - ProfilerManagedToUnmanagedTransitionMD(pFrame->startIp->Method->methodHnd, COR_PRF_TRANSITION_CALL); + ProfilerManagedToUnmanagedTransitionMD(pParam->pFrame->startIp->Method->methodHnd, COR_PRF_TRANSITION_CALL); } #endif - InvokeUnmanagedCalli(ftn, cookie, pArgs, pRet); + InvokeUnmanagedCalli(pParam->ftn, pParam->cookie, pParam->pArgs, pParam->pRet); #ifdef PROFILING_SUPPORTED if (CORProfilerTrackTransitions() && !pFrame->startIp->Method->methodHnd->IsILStub()) { @@ -3147,7 +3149,8 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr } else { - InvokeUnmanagedCalliWithTransition(calliFunctionPointer, cookie, stack, pFrame, callArgsAddress, returnValueAddress); + UnmanagedCalliWithTransiationParam param = { calliFunctionPointer, cookie, stack, pFrame, callArgsAddress, returnValueAddress }; + InvokeUnmanagedCalliWithTransition(¶m); } } #ifndef FEATURE_PORTABLE_ENTRYPOINTS diff --git a/src/coreclr/vm/interpexec.h b/src/coreclr/vm/interpexec.h index 9f234145069595..d377b3c5a57758 100644 --- a/src/coreclr/vm/interpexec.h +++ b/src/coreclr/vm/interpexec.h @@ -160,6 +160,16 @@ struct UnmanagedMethodWithTransitionParam PCODE callTarget; }; +struct UnmanagedCalliWithTransiationParam +{ + PCODE ftn; + void *cookie; + int8_t *stack; + InterpMethodContextFrame *pFrame; + int8_t *pArgs; + int8_t *pRet; +}; + void InterpDispatchCache_ReclaimAll(); void InterpDispatchCache_ClearForLoaderAllocator(LoaderAllocator* pLoaderAllocator); From 42a5defa6beab610332948fffb77c07610f9245f Mon Sep 17 00:00:00 2001 From: DongHeon Jung Date: Wed, 29 Apr 2026 13:27:33 +0900 Subject: [PATCH 2/3] Fix PRECONDITION to use pParam --- src/coreclr/vm/interpexec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index c3d1b5ead7fefb..bf8c0c14f77209 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -293,8 +293,8 @@ void InvokeUnmanagedCalliWithTransition(UnmanagedCalliWithTransiationParam *pPar { THROWS; MODE_COOPERATIVE; - PRECONDITION(CheckPointer((void*)ftn)); - PRECONDITION(CheckPointer(cookie)); + PRECONDITION(CheckPointer((void*)pParam->ftn)); + PRECONDITION(CheckPointer(pParam->cookie)); } CONTRACTL_END From b81e065b095b1d0d167e76c8e90f9e0de1033785 Mon Sep 17 00:00:00 2001 From: DongHeon Jung Date: Wed, 6 May 2026 13:56:31 +0900 Subject: [PATCH 3/3] Fix typo and def --- src/coreclr/vm/interpexec.cpp | 4 ++-- src/coreclr/vm/interpexec.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index c5cf7330ae963a..cbed4789e90778 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -287,7 +287,7 @@ void InvokeUnmanagedMethodWithTransition(UnmanagedMethodWithTransitionParam *pPa } NOINLINE -void InvokeUnmanagedCalliWithTransition(UnmanagedCalliWithTransiationParam *pParam) +void InvokeUnmanagedCalliWithTransition(UnmanagedCalliWithTransitionParam *pParam) { CONTRACTL { @@ -3182,7 +3182,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr } else { - UnmanagedCalliWithTransiationParam param = { calliFunctionPointer, cookie, stack, pFrame, callArgsAddress, returnValueAddress }; + UnmanagedCalliWithTransitionParam param = { calliFunctionPointer, cookie, stack, pFrame, callArgsAddress, returnValueAddress }; InvokeUnmanagedCalliWithTransition(¶m); } } diff --git a/src/coreclr/vm/interpexec.h b/src/coreclr/vm/interpexec.h index 7072a2ad3d3079..96eeaf1202176c 100644 --- a/src/coreclr/vm/interpexec.h +++ b/src/coreclr/vm/interpexec.h @@ -141,7 +141,6 @@ struct CalliStubParam int8_t *pRet; Object** pContinuationRet; }; -#endif // FEATURE_INTERPRETER struct DelegateInvokeMethodParam { @@ -162,7 +161,7 @@ struct UnmanagedMethodWithTransitionParam PCODE callTarget; }; -struct UnmanagedCalliWithTransiationParam +struct UnmanagedCalliWithTransitionParam { PCODE ftn; InterpreterCalliCookie cookie; @@ -171,6 +170,7 @@ struct UnmanagedCalliWithTransiationParam int8_t *pArgs; int8_t *pRet; }; +#endif // FEATURE_INTERPRETER void InterpDispatchCache_ReclaimAll(); void InterpDispatchCache_ClearForLoaderAllocator(LoaderAllocator* pLoaderAllocator);