Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -349,15 +349,15 @@ static CallStubHeader *UpdateCallStubForMethod(MethodDesc *pMD, PCODE target)
header->SetTarget(target);
}

if (pMD->SetCallStub(header))
if (pMD->SetCalliCookie(header))
{
amTracker.SuppressRelease();
}
else
{
// 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;
Expand Down Expand Up @@ -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);
Comment thread
radekdoulik marked this conversation as resolved.
Expand Down Expand Up @@ -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));
Expand All @@ -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
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() };
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/vm/interpexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment thread
radekdoulik marked this conversation as resolved.
Object** pContinuationRet;
};
Comment thread
radekdoulik marked this conversation as resolved.
#endif // FEATURE_INTERPRETER

struct DelegateInvokeMethodParam
{
Expand Down
43 changes: 27 additions & 16 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Comment thread
radekdoulik marked this conversation as resolved.
}

void CInterpreterJitInfo::allocMem(AllocMemArgs *pArgs)
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Comment thread
radekdoulik marked this conversation as resolved.
Comment thread
radekdoulik marked this conversation as resolved.

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

Expand Down
14 changes: 11 additions & 3 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment thread
radekdoulik marked this conversation as resolved.
#endif // FEATURE_INTERPRETER

struct MethodDescCodeData final
{
#ifdef FEATURE_CODE_VERSIONING
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading