diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index d36bb50efde8d6..28c4cb190a41ec 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -206,9 +206,9 @@ static size_t CreateDispatchTokenForMethod(MethodDesc* pMD) void InvokeManagedMethod(ManagedMethodParam *pParam); void InvokeUnmanagedMethod(MethodDesc *targetMethod, int8_t *pArgs, int8_t *pRet, PCODE callTarget); void InvokeCalliStub(CalliStubParam* pParam); -void InvokeUnmanagedCalli(PCODE ftn, void *cookie, int8_t *pArgs, int8_t *pRet); +void InvokeUnmanagedCalli(PCODE ftn, InterpreterCalliCookie cookie, int8_t *pArgs, int8_t *pRet); void InvokeDelegateInvokeMethod(DelegateInvokeMethodParam* pParam); -void* GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD); +InterpreterCalliCookie GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD); extern "C" PCODE CID_VirtualOpenDelegateDispatch(TransitionBlock * pTransitionBlock); // Filter to ignore SEH exceptions representing C++ exceptions. @@ -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(PCODE ftn, InterpreterCalliCookie cookie, int8_t *stack, InterpMethodContextFrame *pFrame, int8_t *pArgs, int8_t *pRet) { CONTRACTL { @@ -349,7 +349,7 @@ static CallStubHeader *UpdateCallStubForMethod(MethodDesc *pMD, PCODE target) header->SetTarget(target); } - if (pMD->SetCallStub(header)) + if (pMD->SetCalliCookie(header)) { amTracker.SuppressRelease(); } @@ -357,7 +357,7 @@ static CallStubHeader *UpdateCallStubForMethod(MethodDesc *pMD, PCODE target) { // We have lost the race for generating the header, use the one that was generated by another thread // and let the amTracker release the memory of the one we generated. - header = pMD->GetCallStub(); + header = pMD->GetCalliCookie(); } return header; @@ -408,7 +408,7 @@ void InvokeManagedMethod(ManagedMethodParam* pParam) PCODE target = pParam->target; Object** pContinuationRet = pParam->pContinuationRet; - CallStubHeader *pHeader = pParam->pMD->GetCallStub(); + CallStubHeader *pHeader = pParam->pMD->GetCalliCookie(); if (pHeader == NULL) { pHeader = UpdateCallStubForMethod(pMD, target == (PCODE)NULL ? pMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY) : target); @@ -467,7 +467,7 @@ void InvokeDelegateInvokeMethod(DelegateInvokeMethodParam* pParam) PCODE target = pParam->target; Object** pContinuationRet = pParam->pContinuationRet; - CallStubHeader *stubHeaderTemplate = pMDDelegateInvoke->GetCallStub(); + CallStubHeader *stubHeaderTemplate = pMDDelegateInvoke->GetCalliCookie(); if (stubHeaderTemplate == NULL) { stubHeaderTemplate = UpdateCallStubForMethod(pMDDelegateInvoke, (PCODE)pMDDelegateInvoke->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY)); @@ -490,7 +490,7 @@ void InvokeDelegateInvokeMethod(DelegateInvokeMethodParam* pParam) pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize, pContinuationRet); } -void InvokeUnmanagedCalli(PCODE ftn, void *cookie, int8_t *pArgs, int8_t *pRet) +void InvokeUnmanagedCalli(PCODE ftn, InterpreterCalliCookie cookie, int8_t *pArgs, int8_t *pRet) { CONTRACTL { @@ -549,7 +549,7 @@ void InvokeCalliStub(CalliStubParam* pParam) pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize, pContinuationRet); } -void* GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD) +InterpreterCalliCookie GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD) { STANDARD_VM_CONTRACT; @@ -3123,7 +3123,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int32_t calliCookie = ip[4]; int32_t flags = ip[5]; - void* cookie = pMethod->pDataItems[calliCookie]; + InterpreterCalliCookie cookie = (InterpreterCalliCookie)pMethod->pDataItems[calliCookie]; ip += 6; // Save current execution state for when we return from called method @@ -3167,8 +3167,15 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr if (PortableEntryPoint::PrefersInterpreterEntryPoint(calliFunctionPointer) || !PortableEntryPoint::HasNativeEntryPoint(calliFunctionPointer)) goto CALL_INTERP_METHOD; - MetaSig sig(targetMethod); - cookie = GetCookieForCalliSig(sig, NULL); + cookie = targetMethod->GetCalliCookie(); + if (cookie == NULL) + { + MetaSig sig(targetMethod); + cookie = GetCookieForCalliSig(sig, NULL); + _ASSERTE(cookie != NULL); + targetMethod->SetCalliCookie(cookie); + cookie = targetMethod->GetCalliCookie(); + } #endif // FEATURE_PORTABLE_ENTRYPOINTS frameNeedsTailcallUpdate = false; CalliStubParam param = { calliFunctionPointer, cookie, callArgsAddress, returnValueAddress, pInterpreterFrame->GetContinuationPtr() }; diff --git a/src/coreclr/vm/interpexec.h b/src/coreclr/vm/interpexec.h index 9f234145069595..1192ddadf0cdbe 100644 --- a/src/coreclr/vm/interpexec.h +++ b/src/coreclr/vm/interpexec.h @@ -132,14 +132,16 @@ struct ManagedMethodParam void InvokeManagedMethod(ManagedMethodParam *pParam); +#ifdef FEATURE_INTERPRETER struct CalliStubParam { PCODE ftn; - void* cookie; + InterpreterCalliCookie cookie; int8_t *pArgs; int8_t *pRet; Object** pContinuationRet; }; +#endif // FEATURE_INTERPRETER struct DelegateInvokeMethodParam { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index fda3b8af014b87..64c4f087d9536b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11490,25 +11490,13 @@ LPVOID CEEInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) #ifdef FEATURE_INTERPRETER // Forward declare the function for mapping MetaSig to a cookie. -void* GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD); +InterpreterCalliCookie GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD); LPVOID CInterpreterJitInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) { - void* result = NULL; + InterpreterCalliCookie result = NULL; JIT_TO_EE_TRANSITION(); - Instantiation classInst = Instantiation((TypeHandle*) szMetaSig->sigInst.classInst, szMetaSig->sigInst.classInstCount); - Instantiation methodInst = Instantiation((TypeHandle*) szMetaSig->sigInst.methInst, szMetaSig->sigInst.methInstCount); - SigTypeContext typeContext = SigTypeContext(classInst, methodInst); - Module* mod = GetModule(szMetaSig->scope); - - MetaSig sig(szMetaSig->pSig, szMetaSig->cbSig, mod, &typeContext); - - if (szMetaSig->isAsyncCall()) - sig.SetIsAsyncCall(); - - _ASSERTE(szMetaSig->isAsyncCall() == sig.IsAsyncCall()); - // When compiling a calli inside an IL stub for a P/Invoke, pass the target // P/Invoke MethodDesc so ComputeCallStub can detect the Swift calling convention. MethodDesc* pContextMD = nullptr; @@ -11518,12 +11506,35 @@ LPVOID CInterpreterJitInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* sz if (pTargetMD != nullptr) { pContextMD = pTargetMD; + result = pTargetMD->GetCalliCookie(); + } + } + + if (result == NULL) + { + Instantiation classInst = Instantiation((TypeHandle*) szMetaSig->sigInst.classInst, szMetaSig->sigInst.classInstCount); + Instantiation methodInst = Instantiation((TypeHandle*) szMetaSig->sigInst.methInst, szMetaSig->sigInst.methInstCount); + SigTypeContext typeContext = SigTypeContext(classInst, methodInst); + Module* mod = GetModule(szMetaSig->scope); + + MetaSig sig(szMetaSig->pSig, szMetaSig->cbSig, mod, &typeContext); + + if (szMetaSig->isAsyncCall()) + sig.SetIsAsyncCall(); + + _ASSERTE(szMetaSig->isAsyncCall() == sig.IsAsyncCall()); + + result = GetCookieForCalliSig(sig, pContextMD); + + if (pContextMD != nullptr) + { + pContextMD->SetCalliCookie(result); + result = pContextMD->GetCalliCookie(); } } - result = GetCookieForCalliSig(sig, pContextMD); EE_TO_JIT_TRANSITION(); - return result; + return (void*)result; } void CInterpreterJitInfo::allocMem(AllocMemArgs *pArgs) diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index d48075fc0b5c01..be6faab57943a1 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -300,26 +300,26 @@ PatchpointInfo* MethodDesc::GetMethodDescAltJitPatchpointInfo() #endif // FEATURE_CODE_VERSIONING #ifdef FEATURE_INTERPRETER -// Set the call stub for the interpreter to JIT/AOT calls -// Returns true if the current call set the stub, false if it was already set -bool MethodDesc::SetCallStub(CallStubHeader *pHeader) +// Cache the calli cookie on the MethodDesc +// Returns true if the current call set the cookie, false if it was already set +bool MethodDesc::SetCalliCookie(InterpreterCalliCookie cookie) { STANDARD_VM_CONTRACT; IfFailThrow(EnsureCodeDataExists(NULL)); _ASSERTE(m_codeData != NULL); - return InterlockedCompareExchangeT(&m_codeData->CallStub, pHeader, NULL) == NULL; + return InterlockedCompareExchangeT((void**)&m_codeData->CalliCookie, (void*)cookie, (void*)NULL) == NULL; } -CallStubHeader *MethodDesc::GetCallStub() +InterpreterCalliCookie MethodDesc::GetCalliCookie() { LIMITED_METHOD_CONTRACT; PTR_MethodDescCodeData codeData = VolatileLoadWithoutBarrier(&m_codeData); if (codeData == NULL) return NULL; - return VolatileLoadWithoutBarrier(&codeData->CallStub); + return (InterpreterCalliCookie)VolatileLoadWithoutBarrier(&codeData->CalliCookie); } #endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 29b76fd0fede96..a66e10b4548c95 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -249,6 +249,14 @@ enum MethodDescFlags }; // Used for storing additional items related to native code +#ifdef FEATURE_INTERPRETER +#ifdef FEATURE_PORTABLE_ENTRYPOINTS +typedef void(*InterpreterCalliCookie)(PCODE, int8_t*, int8_t*); +#else +typedef CallStubHeader* InterpreterCalliCookie; +#endif // FEATURE_PORTABLE_ENTRYPOINTS +#endif // FEATURE_INTERPRETER + struct MethodDescCodeData final { #ifdef FEATURE_CODE_VERSIONING @@ -257,7 +265,7 @@ struct MethodDescCodeData final #endif // FEATURE_CODE_VERSIONING PCODE TemporaryEntryPoint; #ifdef FEATURE_INTERPRETER - CallStubHeader *CallStub; + InterpreterCalliCookie CalliCookie; #endif // FEATURE_INTERPRETER #if defined(_DEBUG) && defined(ALLOW_SXS_JIT) PatchpointInfo *AltJitPatchpointInfo; @@ -1976,8 +1984,8 @@ class MethodDesc #endif //!DACCESS_COMPILE #if defined(FEATURE_INTERPRETER) && !defined(DACCESS_COMPILE) - bool SetCallStub(CallStubHeader *pHeader); - CallStubHeader *GetCallStub(); + bool SetCalliCookie(InterpreterCalliCookie cookie); + InterpreterCalliCookie GetCalliCookie(); #endif // FEATURE_INTERPRETER && !DACCESS_COMPILE #ifdef FEATURE_CODE_VERSIONING diff --git a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp index c0265475c3447d..2e0086843ade1a 100644 --- a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp +++ b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp @@ -20,32 +20,36 @@ namespace { - NOINLINE static void CallFunc_F64_F64_F64_RetF64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F64_F64_F64_RetF64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; double (*fptr)(int*, double, double, double, PCODE) = (double (*)(int*, double, double, double, PCODE))pcode; - *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_F64(1), ARG_F64(2), pPortableEntryPointContext); + *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_F64(1), ARG_F64(2), pPortableEntryPoint); } - NOINLINE static void CallFunc_F64_F64_RetF64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F64_F64_RetF64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; double (*fptr)(int*, double, double, PCODE) = (double (*)(int*, double, double, PCODE))pcode; - *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_F64(1), pPortableEntryPointContext); + *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_F64(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_F64_I32_RetF64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F64_I32_RetF64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; double (*fptr)(int*, double, int32_t, PCODE) = (double (*)(int*, double, int32_t, PCODE))pcode; - *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_I32(1), pPortableEntryPointContext); + *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), ARG_I32(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_F64_RetF64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F64_RetF64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; double (*fptr)(int*, double, PCODE) = (double (*)(int*, double, PCODE))pcode; - *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), pPortableEntryPointContext); + *((double*)pRet) = (*fptr)(&framePointer, ARG_F64(0), pPortableEntryPoint); } static void CallFunc_I32_RetF64(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -54,32 +58,36 @@ namespace *((double*)pRet) = (*fptr)(ARG_I32(0)); } - NOINLINE static void CallFunc_F32_F32_F32_RetF32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F32_F32_F32_RetF32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; float (*fptr)(int*, float, float, float, PCODE) = (float (*)(int*, float, float, float, PCODE))pcode; - *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_F32(1), ARG_F32(2), pPortableEntryPointContext); + *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_F32(1), ARG_F32(2), pPortableEntryPoint); } - NOINLINE static void CallFunc_F32_F32_RetF32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F32_F32_RetF32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; float (*fptr)(int*, float, float, PCODE) = (float (*)(int*, float, float, PCODE))pcode; - *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_F32(1), pPortableEntryPointContext); + *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_F32(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_F32_I32_RetF32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F32_I32_RetF32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; float (*fptr)(int*, float, int32_t, PCODE) = (float (*)(int*, float, int32_t, PCODE))pcode; - *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_I32(1), pPortableEntryPointContext); + *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), ARG_I32(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_F32_RetF32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F32_RetF32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; float (*fptr)(int*, float, PCODE) = (float (*)(int*, float, PCODE))pcode; - *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), pPortableEntryPointContext); + *((float*)pRet) = (*fptr)(&framePointer, ARG_F32(0), pPortableEntryPoint); } static void CallFunc_Void_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -136,25 +144,28 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), ARG_I32(6), ARG_I32(7), ARG_I32(8), ARG_I32(9), ARG_I32(10), ARG_I32(11), ARG_I32(12), ARG_I32(13)); } - NOINLINE static void CallFunc_I32_I32_I32_I32_I32_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_I32_I32_I32_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, PCODE) = (int32_t (*)(int*, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), pPortableEntryPoint); } - NOINLINE static void CallFunc_I32_I32_I32_I32_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_I32_I32_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, int32_t, int32_t, int32_t, int32_t, PCODE) = (int32_t (*)(int*, int32_t, int32_t, int32_t, int32_t, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), pPortableEntryPoint); } - NOINLINE static void CallFunc_I32_I32_I32_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_I32_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, int32_t, int32_t, int32_t, PCODE) = (int32_t (*)(int*, int32_t, int32_t, int32_t, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), pPortableEntryPoint); } static void CallFunc_I32_I32_I32_I64_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -169,11 +180,12 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_IND(3), ARG_I32(4)); } - NOINLINE static void CallFunc_I32_I32_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, int32_t, int32_t, PCODE) = (int32_t (*)(int*, int32_t, int32_t, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPoint); } static void CallFunc_I32_I32_I64_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -194,11 +206,12 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_IND(2), ARG_I32(3), ARG_I32(4), ARG_IND(5)); } - NOINLINE static void CallFunc_I32_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, int32_t, PCODE) = (int32_t (*)(int*, int32_t, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), pPortableEntryPoint); } static void CallFunc_I32_I64_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -243,11 +256,12 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_IND(1), ARG_I32(2), ARG_I32(3), ARG_I32(4)); } - NOINLINE static void CallFunc_I32_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, int32_t, PCODE) = (int32_t (*)(int*, int32_t, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPoint); } static void CallFunc_I64_I32_I64_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -328,11 +342,12 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_IND(0), ARG_IND(1), ARG_IND(2)); } - NOINLINE static void CallFunc_Void_RetI32_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_Void_RetI32_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int32_t (*fptr)(int*, PCODE) = (int32_t (*)(int*, PCODE))pcode; - *((int32_t*)pRet) = (*fptr)(&framePointer, pPortableEntryPointContext); + *((int32_t*)pRet) = (*fptr)(&framePointer, pPortableEntryPoint); } static void CallFunc_Void_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -365,39 +380,44 @@ namespace *((int64_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I64(1), ARG_I32(2)); } - NOINLINE static void CallFunc_I32_I64_I64_RetI64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I64_I64_RetI64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int64_t (*fptr)(int*, int32_t, int64_t, int64_t, PCODE) = (int64_t (*)(int*, int32_t, int64_t, int64_t, PCODE))pcode; - *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I64(1), ARG_I64(2), pPortableEntryPointContext); + *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I64(1), ARG_I64(2), pPortableEntryPoint); } - NOINLINE static void CallFunc_I32_I64_RetI64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I64_RetI64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int64_t (*fptr)(int*, int32_t, int64_t, PCODE) = (int64_t (*)(int*, int32_t, int64_t, PCODE))pcode; - *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I64(1), pPortableEntryPointContext); + *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), ARG_I64(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_I32_RetI64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_RetI64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int64_t (*fptr)(int*, int32_t, PCODE) = (int64_t (*)(int*, int32_t, PCODE))pcode; - *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPointContext); + *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPoint); } - NOINLINE static void CallFunc_I64_I64_RetI64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I64_I64_RetI64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int64_t (*fptr)(int*, int64_t, int64_t, PCODE) = (int64_t (*)(int*, int64_t, int64_t, PCODE))pcode; - *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I64(0), ARG_I64(1), pPortableEntryPointContext); + *((int64_t*)pRet) = (*fptr)(&framePointer, ARG_I64(0), ARG_I64(1), pPortableEntryPoint); } - NOINLINE static void CallFunc_Void_RetI64_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_Void_RetI64_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; int64_t (*fptr)(int*, PCODE) = (int64_t (*)(int*, PCODE))pcode; - *((int64_t*)pRet) = (*fptr)(&framePointer, pPortableEntryPointContext); + *((int64_t*)pRet) = (*fptr)(&framePointer, pPortableEntryPoint); } static void CallFunc_Void_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -406,18 +426,20 @@ namespace (*fptr)(); } - NOINLINE static void CallFunc_F64_I32_I32_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F64_I32_I32_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, double, int32_t, int32_t, PCODE) = (void (*)(int*, double, int32_t, int32_t, PCODE))pcode; - (*fptr)(&framePointer, ARG_F64(0), ARG_I32(1), ARG_I32(2), pPortableEntryPointContext); + (*fptr)(&framePointer, ARG_F64(0), ARG_I32(1), ARG_I32(2), pPortableEntryPoint); } - NOINLINE static void CallFunc_F32_I32_I32_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_F32_I32_I32_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, float, int32_t, int32_t, PCODE) = (void (*)(int*, float, int32_t, int32_t, PCODE))pcode; - (*fptr)(&framePointer, ARG_F32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPointContext); + (*fptr)(&framePointer, ARG_F32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPoint); } static void CallFunc_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -468,11 +490,12 @@ namespace (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_IND(3), ARG_IND(4), ARG_I32(5)); } - NOINLINE static void CallFunc_I32_I32_I32_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_I32_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, int32_t, int32_t, int32_t, PCODE) = (void (*)(int*, int32_t, int32_t, int32_t, PCODE))pcode; - (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPointContext); + (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), ARG_I32(2), pPortableEntryPoint); } static void CallFunc_I32_I32_IND_IND_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -487,11 +510,12 @@ namespace (*fptr)(ARG_I32(0), ARG_I32(1), ARG_IND(2), ARG_IND(3), ARG_I32(4), ARG_I32(5)); } - NOINLINE static void CallFunc_I32_I32_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_I32_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, int32_t, int32_t, PCODE) = (void (*)(int*, int32_t, int32_t, PCODE))pcode; - (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), pPortableEntryPointContext); + (*fptr)(&framePointer, ARG_I32(0), ARG_I32(1), pPortableEntryPoint); } static void CallFunc_I32_IND_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -500,11 +524,12 @@ namespace (*fptr)(ARG_I32(0), ARG_IND(1), ARG_I32(2)); } - NOINLINE static void CallFunc_I32_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_I32_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, int32_t, PCODE) = (void (*)(int*, int32_t, PCODE))pcode; - (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPointContext); + (*fptr)(&framePointer, ARG_I32(0), pPortableEntryPoint); } static void CallFunc_I64_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -573,11 +598,12 @@ namespace (*fptr)(ARG_IND(0), ARG_IND(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), ARG_I32(6)); } - NOINLINE static void CallFunc_Void_RetVoid_PE(PCODE pcode, int8_t* pArgs, int8_t* pRet, PCODE pPortableEntryPointContext) + NOINLINE static void CallFunc_Void_RetVoid_PE(PCODE pPortableEntryPoint, int8_t* pArgs, int8_t* pRet) { + PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint); alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK; void (*fptr)(int*, PCODE) = (void (*)(int*, PCODE))pcode; - (*fptr)(&framePointer, pPortableEntryPointContext); + (*fptr)(&framePointer, pPortableEntryPoint); } } diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index bcc938905914a4..191122e19fe148 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -736,15 +736,16 @@ void InvokeCalliStub(CalliStubParam* pParam) _ASSERTE(pParam->ftn != (PCODE)NULL); _ASSERTE(pParam->cookie != NULL); - PCODE actualFtn = (PCODE)PortableEntryPoint::GetActualCode(pParam->ftn); - ((void(*)(PCODE, int8_t*, int8_t*, PCODE))pParam->cookie)(actualFtn, pParam->pArgs, pParam->pRet, pParam->ftn); + MethodDesc* md = PortableEntryPoint::GetMethodDesc(pParam->ftn); + + (pParam->cookie)(pParam->ftn, pParam->pArgs, pParam->pRet); } -void InvokeUnmanagedCalli(PCODE ftn, void *cookie, int8_t *pArgs, int8_t *pRet) +void InvokeUnmanagedCalli(PCODE ftn, InterpreterCalliCookie cookie, int8_t *pArgs, int8_t *pRet) { _ASSERTE(ftn != (PCODE)NULL); _ASSERTE(cookie != NULL); - ((void(*)(PCODE, int8_t*, int8_t*))cookie)(ftn, pArgs, pRet); + (cookie)(ftn, pArgs, pRet); } void InvokeDelegateInvokeMethod(DelegateInvokeMethodParam* pParam) @@ -902,13 +903,13 @@ namespace static StringToWasmSigThunkHash* thunkCache = nullptr; static StringToWasmSigThunkHash* portableEntrypointThunkCache = nullptr; - void* LookupThunk(const char* key) + InterpreterCalliCookie LookupThunk(const char* key) { StringToWasmSigThunkHash* table = thunkCache; _ASSERTE(table != nullptr && "Wasm thunk cache not initialized. Call InitializeWasmThunkCaches() at EEStartup."); void* thunk; bool success = table->Lookup(key, &thunk); - return success ? thunk : nullptr; + return success ? (InterpreterCalliCookie)thunk : nullptr; } void* LookupPortableEntryPointThunk(const char* key) @@ -921,7 +922,7 @@ namespace } // This is a simple signature computation routine for signatures currently supported in the wasm environment. - void* ComputeCalliSigThunk(MetaSig& sig) + InterpreterCalliCookie ComputeCalliSigThunk(MetaSig& sig) { STANDARD_VM_CONTRACT; _ASSERTE(sizeof(int32_t) == sizeof(void*)); @@ -944,7 +945,7 @@ namespace if (!GetSignatureKey(sig, keyBuffer, keyBufferLen)) return NULL; - void* thunk = LookupThunk(keyBuffer); + InterpreterCalliCookie thunk = LookupThunk(keyBuffer); #ifdef _DEBUG if (thunk == NULL) printf("WASM calli missing for key: %s\n", keyBuffer); @@ -1118,11 +1119,11 @@ void InitializeWasmThunkCaches() } } -void* GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD) +InterpreterCalliCookie GetCookieForCalliSig(MetaSig metaSig, MethodDesc *pContextMD) { STANDARD_VM_CONTRACT; - void* thunk = ComputeCalliSigThunk(metaSig); + InterpreterCalliCookie thunk = ComputeCalliSigThunk(metaSig); if (thunk == NULL) { PORTABILITY_ASSERT("GetCookieForCalliSig: unknown thunk signature"); @@ -1190,10 +1191,15 @@ void* GetUnmanagedCallersOnlyThunk(MethodDesc* pMD) void InvokeManagedMethod(ManagedMethodParam *pParam) { - MetaSig sig(pParam->pMD); - void* cookie = GetCookieForCalliSig(sig, pParam->pMD); - - _ASSERTE(cookie != NULL); + InterpreterCalliCookie cookie = pParam->pMD->GetCalliCookie(); + if (cookie == NULL) + { + MetaSig sig(pParam->pMD); + cookie = GetCookieForCalliSig(sig, pParam->pMD); + _ASSERTE(cookie != NULL); + pParam->pMD->SetCalliCookie(cookie); + cookie = pParam->pMD->GetCalliCookie(); + } CalliStubParam param = { pParam->target == NULL ? pParam->pMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY) : pParam->target, cookie, pParam->pArgs, pParam->pRet, pParam->pContinuationRet }; InvokeCalliStub(¶m); diff --git a/src/tasks/WasmAppBuilder/coreclr/InterpToNativeGenerator.cs b/src/tasks/WasmAppBuilder/coreclr/InterpToNativeGenerator.cs index 711b88198e1062..d48e1308adf72f 100644 --- a/src/tasks/WasmAppBuilder/coreclr/InterpToNativeGenerator.cs +++ b/src/tasks/WasmAppBuilder/coreclr/InterpToNativeGenerator.cs @@ -105,14 +105,14 @@ private static void Emit(StreamWriter w, IEnumerable cookies) var portableEntryPointComma = signature.Length > 1 ? ", " : ""; var portableEntrypointDeclaration = isPortableEntryPointCall ? portableEntryPointComma + "PCODE" : ""; - var portableEntrypointParam = isPortableEntryPointCall ? portableEntryPointComma + "pPortableEntryPointContext" : ""; + var portableEntrypointParam = isPortableEntryPointCall ? portableEntryPointComma + "pPortableEntryPoint" : ""; var portableEntrypointStackDeclaration = isPortableEntryPointCall ? "int*, " : ""; var portableEntrypointStackParam = isPortableEntryPointCall ? "&framePointer, " : ""; w.Write( $$""" - {{(isPortableEntryPointCall ? "NOINLINE " : "")}}static void {{CallFuncName(args, SignatureMapper.CharToNameType(signature[0]), isPortableEntryPointCall)}}(PCODE pcode, int8_t* pArgs, int8_t* pRet{{(isPortableEntryPointCall ? ", PCODE pPortableEntryPointContext" : "")}}) - {{{(isPortableEntryPointCall ? "\n alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK;" : "")}} + {{(isPortableEntryPointCall ? "NOINLINE " : "")}}static void {{CallFuncName(args, SignatureMapper.CharToNameType(signature[0]), isPortableEntryPointCall)}}(PCODE {{(isPortableEntryPointCall ? "pPortableEntryPoint" : "pcode")}}, int8_t* pArgs, int8_t* pRet) + {{{(isPortableEntryPointCall ? "\n PCODE pcode = (PCODE)PortableEntryPoint::GetActualCode(pPortableEntryPoint);\n alignas(16) int framePointer = TERMINATE_R2R_STACK_WALK;" : "")}} {{result.nativeType}} (*fptr)({{portableEntrypointStackDeclaration}}{{args.Join(", ", (p, i) => SignatureMapper.CharToNativeType(p))}}{{portableEntrypointDeclaration}}) = ({{result.nativeType}} (*)({{portableEntrypointStackDeclaration}}{{args.Join(", ", (p, i) => SignatureMapper.CharToNativeType(p))}}{{portableEntrypointDeclaration}}))pcode; {{portabilityAssert}}{{(result.isVoid ? "" : "*" + "((" + result.nativeType + "*)pRet) = ")}}(*fptr)({{portableEntrypointStackParam}}{{args.Join(", ", (p, i) => $"{SignatureMapper.CharToArgType(p)}({i})")}}{{portableEntrypointParam}}); }