Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
11 changes: 10 additions & 1 deletion src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,16 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
}
else
{
InvokeCalliStub(LOCAL_VAR(calliFunctionPointerVar, PCODE), cookie, stack + callArgsOffset, stack + returnOffset);
PCODE calliFunctionPointer = LOCAL_VAR(calliFunctionPointerVar, PCODE);
#ifdef FEATURE_PORTABLE_ENTRYPOINTS
if (!PortableEntryPoint::HasNativeEntryPoint(calliFunctionPointer))
{
targetMethod = PortableEntryPoint::GetMethodDesc(calliFunctionPointer);
goto CALL_INTERP_METHOD;
}
#else // FEATURE_PORTABLE_ENTRYPOINTS
InvokeCalliStub(calliFunctionPointer, cookie, stack + callArgsOffset, stack + returnOffset);
#endif // FEATURE_PORTABLE_ENTRYPOINTS
}

break;
Expand Down
124 changes: 67 additions & 57 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10749,7 +10749,7 @@ CEECodeGenInfo::CEECodeGenInfo(PrepareCodeConfig* config, MethodDesc* fd, COR_IL

void CEECodeGenInfo::getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
CORINFO_CONST_LOOKUP* pNativeEntrypoint, /* OUT */
CORINFO_METHOD_HANDLE* pMethod) /* OUT */
CORINFO_METHOD_HANDLE* pMethodHandle) /* OUT */
{
CONTRACTL
{
Expand All @@ -10765,61 +10765,17 @@ void CEECodeGenInfo::getHelperFtn(CorInfoHelpFunc ftnNum, /* IN

InfoAccessType accessType;
LPVOID targetAddr;

MethodDesc* helperMD = NULL;
VMHELPDEF const& helperDef = hlpFuncTable[ftnNum];
PCODE pfnHelper = helperDef.pfnHelper;

DynamicCorInfoHelpFunc dynamicFtnNum;

#ifdef FEATURE_PORTABLE_ENTRYPOINTS

accessType = IAT_VALUE;
targetAddr = (LPVOID)VolatileLoad(&hlpFuncEntryPoints[ftnNum]);
if (targetAddr != NULL)
{
// If the target address is already cached, but the caller asked for the method handle
// then we verify the helper is an IL based dynamic helper and load the method handle for it.
if (pMethod != NULL
&& helperDef.IsDynamicHelper(&dynamicFtnNum)
&& HasILBasedDynamicJitHelper(dynamicFtnNum))
{
helperMD = GetMethodDescForILBasedDynamicJitHelper(dynamicFtnNum);
_ASSERTE(PortableEntryPoint::GetMethodDesc((PCODE)targetAddr) == helperMD);
}
}
else
{
if (helperDef.IsDynamicHelper(&dynamicFtnNum))
{
pfnHelper = LoadDynamicJitHelper(dynamicFtnNum);
if (HasILBasedDynamicJitHelper(dynamicFtnNum))
helperMD = GetMethodDescForILBasedDynamicJitHelper(dynamicFtnNum);
}

// LoadDynamicJitHelper returns PortableEntryPoint for helpers backed by managed methods. We need to wrap
// the code address by PortableEntryPoint in all other cases.
if (helperMD == NULL)
{
_ASSERTE(pfnHelper != NULL);
AllocMemHolder<PortableEntryPoint> portableEntryPoint = SystemDomain::GetGlobalLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T{ sizeof(PortableEntryPoint) });
portableEntryPoint->Init((void*)pfnHelper);
pfnHelper = (PCODE)(PortableEntryPoint*)(portableEntryPoint);

if (InterlockedCompareExchangeT<PCODE>(&hlpFuncEntryPoints[ftnNum], pfnHelper, (PCODE)NULL) == (PCODE)NULL)
portableEntryPoint.SuppressRelease();
pfnHelper = hlpFuncEntryPoints[ftnNum];
}
else
{
VolatileStore(&hlpFuncEntryPoints[ftnNum], pfnHelper);
}

targetAddr = (LPVOID)pfnHelper;
}
targetAddr = (LPVOID)getHelperFtnStatic(ftnNum, &helperMD);

#else // !FEATURE_PORTABLE_ENTRYPOINTS
VMHELPDEF const& helperDef = hlpFuncTable[ftnNum];

DynamicCorInfoHelpFunc dynamicFtnNum;
PCODE pfnHelper = helperDef.pfnHelper;
if (helperDef.IsDynamicHelper(&dynamicFtnNum))
{
#if defined(TARGET_AMD64)
Expand Down Expand Up @@ -10853,7 +10809,7 @@ void CEECodeGenInfo::getHelperFtn(CorInfoHelpFunc ftnNum, /* IN
{
accessType = IAT_VALUE;
targetAddr = finalTierAddr;
if (pMethod != NULL && HasILBasedDynamicJitHelper(dynamicFtnNum))
if (pMethodHandle != NULL && HasILBasedDynamicJitHelper(dynamicFtnNum))
{
helperMD = GetMethodDescForILBasedDynamicJitHelper(dynamicFtnNum);
_ASSERT(helperMD != NULL);
Expand Down Expand Up @@ -10939,30 +10895,84 @@ exit: ;
pNativeEntrypoint->addr = targetAddr;
}

if (pMethod != NULL)
*pMethod = (CORINFO_METHOD_HANDLE)helperMD;
if (pMethodHandle != NULL)
*pMethodHandle = (CORINFO_METHOD_HANDLE)helperMD;

EE_TO_JIT_TRANSITION();
}

PCODE CEECodeGenInfo::getHelperFtnStatic(CorInfoHelpFunc ftnNum)
PCODE CEECodeGenInfo::getHelperFtnStatic(CorInfoHelpFunc ftnNum, MethodDesc** pMethod)
{
CONTRACTL {
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_PREEMPTIVE;
} CONTRACTL_END;
}
CONTRACTL_END;

VMHELPDEF const& helperDef = hlpFuncTable[ftnNum];
PCODE pfnHelper = helperDef.pfnHelper;

PCODE pfnHelper;
MethodDesc* helperMD = NULL;
DynamicCorInfoHelpFunc dynamicFtnNum;

#ifdef FEATURE_PORTABLE_ENTRYPOINTS
pfnHelper = VolatileLoad(&hlpFuncEntryPoints[ftnNum]);
if (pfnHelper != (PCODE)NULL)
{
// If the target address is already cached, but the caller asked for the method handle
// then we verify the helper is an IL based dynamic helper and load the method handle for it.
if (pMethod != NULL
&& helperDef.IsDynamicHelper(&dynamicFtnNum)
&& HasILBasedDynamicJitHelper(dynamicFtnNum))
{
helperMD = GetMethodDescForILBasedDynamicJitHelper(dynamicFtnNum);
_ASSERTE(PortableEntryPoint::GetMethodDesc(pfnHelper) == helperMD);
}
}
else
{
pfnHelper = helperDef.pfnHelper;
if (helperDef.IsDynamicHelper(&dynamicFtnNum))
{
pfnHelper = LoadDynamicJitHelper(dynamicFtnNum);
if (HasILBasedDynamicJitHelper(dynamicFtnNum))
helperMD = GetMethodDescForILBasedDynamicJitHelper(dynamicFtnNum);
}

// LoadDynamicJitHelper returns PortableEntryPoint for helpers backed by managed methods. We need to wrap
// the code address by PortableEntryPoint in all other cases.
if (helperMD == NULL)
{
_ASSERTE(pfnHelper != NULL);
AllocMemHolder<PortableEntryPoint> portableEntryPoint = SystemDomain::GetGlobalLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T{ sizeof(PortableEntryPoint) });
portableEntryPoint->Init((void*)pfnHelper);
pfnHelper = (PCODE)(PortableEntryPoint*)(portableEntryPoint);

if (InterlockedCompareExchangeT<PCODE>(&hlpFuncEntryPoints[ftnNum], pfnHelper, (PCODE)NULL) == (PCODE)NULL)
portableEntryPoint.SuppressRelease();
pfnHelper = hlpFuncEntryPoints[ftnNum];
}
else
{
VolatileStore(&hlpFuncEntryPoints[ftnNum], pfnHelper);
}
}

#else // !FEATURE_PORTABLE_ENTRYPOINTS
pfnHelper = helperDef.pfnHelper;

// In this case we need to find the actual pfnHelper
// using an extra indirection.
DynamicCorInfoHelpFunc dynamicFtnNum;
if (helperDef.IsDynamicHelper(&dynamicFtnNum))
{
pfnHelper = LoadDynamicJitHelper(dynamicFtnNum);
}
#endif // FEATURE_PORTABLE_ENTRYPOINTS

if (pMethod != NULL)
*pMethod = helperMD;

_ASSERTE(pfnHelper != (PCODE)NULL);

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/jitinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ class CEECodeGenInfo : public CEEInfo
void getHelperFtn(CorInfoHelpFunc tnNum, /* IN */
CORINFO_CONST_LOOKUP * pNativeEntrypoint, /* OUT */
CORINFO_METHOD_HANDLE * pMethodHandle) override; /* OUT */
static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum);
static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum, MethodDesc** pMethod /* OUT */ = NULL);

InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue) override;
InfoAccessType emptyStringLiteral(void ** ppValue) override;
Expand Down
Loading
Loading