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
33 changes: 14 additions & 19 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7514,6 +7514,7 @@ static bool getILIntrinsicImplementationForActivator(MethodDesc* ftn,
//
COR_ILMETHOD_DECODER* CEEInfo::getMethodInfoWorker(
MethodDesc* ftn,
MethodDesc* ilFtn,
COR_ILMETHOD_DECODER* header,
Comment thread
jakobbotsch marked this conversation as resolved.
CORINFO_METHOD_INFO* methInfo,
CORINFO_CONTEXT_HANDLE exactContext)
Expand All @@ -7530,10 +7531,6 @@ COR_ILMETHOD_DECODER* CEEInfo::getMethodInfoWorker(
/* Grab information from the IL header */
SigPointer localSig{};

// For async versions we get the IL of the ordinary variant and pass the
// JIT a flag indicating that.
MethodDesc* ilFtn = ftn->SupportsAsyncVersionCodegen() ? ftn->GetOrdinaryVariant() : ftn;

MethodInfoWorkerContext cxt{ ftn, header };

TransientMethodDetails* detailsMaybe = NULL;
Expand Down Expand Up @@ -7740,22 +7737,24 @@ CEEInfo::getMethodInfo(
JIT_TO_EE_TRANSITION();

MethodDesc* ftn = GetMethod(ftnHnd);
MethodDesc* ilFtn = ftn->GetOrdinaryVariantIfAsyncVersion();

COR_ILMETHOD* pILHeader;
if (ftn->MayHaveILHeader() && (pILHeader = ftn->GetILHeader()) != NULL)
if (ilFtn->MayHaveILHeader() && (pILHeader = ilFtn->GetILHeader()) != NULL)
{
// Get the IL header and set it.
COR_ILMETHOD_DECODER header(pILHeader, ftn->GetMDImport(), NULL);
getMethodInfoWorker(ftn, &header, methInfo, context);
COR_ILMETHOD_DECODER header(pILHeader, ilFtn->GetMDImport(), NULL);
getMethodInfoWorker(ftn, ilFtn, &header, methInfo, context);
result = true;
}
else if (ftn->IsIL() || ftn->IsDynamicMethod())
else if (ilFtn->IsIL() || ilFtn->IsDynamicMethod())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change to use ilFtn in this check is the actual fix for the problem, the rest is just avoiding multiple GetOrdinaryVariant calls.

{
// IL methods with no IL header indicate there is no implementation defined in metadata.
// NOTE: P/Invoke methods are also IL methods with no IL header,
// but it is generally not profitable to inline the marshalling IL.
// As a result, we skip inlining the marshalling IL.
// NOTE: P/Invoke methods have marshalling IL but it is generally not
// profitable to inline it. The IsIL check above returns false for them
// and thus we will not inline them.
// P/Invokes that don't require marshalling can still be inlined directly by the JIT.
getMethodInfoWorker(ftn, NULL, methInfo, context);
getMethodInfoWorker(ftn, ilFtn, NULL, methInfo, context);
result = true;
}

Expand Down Expand Up @@ -7940,7 +7939,7 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
else if (pCallee->IsIL())
{
CORINFO_METHOD_INFO methodInfo;
getMethodInfoWorker(pCallee, NULL, &methodInfo);
getMethodInfoWorker(pCallee, pCallee->GetOrdinaryVariantIfAsyncVersion(), NULL, &methodInfo);
if (methodInfo.EHcount > 0)
{
result = INLINE_FAIL;
Expand Down Expand Up @@ -10975,7 +10974,7 @@ CEECodeGenInfo::CEECodeGenInfo(PrepareCodeConfig* config, MethodDesc* fd, COR_IL
{
STANDARD_VM_CONTRACT;
_ASSERTE(config != NULL);
COR_ILMETHOD_DECODER* ilHeader = getMethodInfoWorker(m_pMethodBeingCompiled, m_ILHeader, &m_MethodInfo);
COR_ILMETHOD_DECODER* ilHeader = getMethodInfoWorker(m_pMethodBeingCompiled, m_pMethodBeingCompiled->GetOrdinaryVariantIfAsyncVersion(), m_ILHeader, &m_MethodInfo);

// The header maybe replaced during the call to getMethodInfoWorker. This is most probable
// when the input is null (that is, no metadata), but we can also examine the method and generate
Expand Down Expand Up @@ -13150,11 +13149,7 @@ void CEECodeGenInfo::getEHinfo(

bool isMethodBeingCompiled = pMD == m_pMethodBeingCompiled;

if (pMD->SupportsAsyncVersionCodegen())
{
// Get the EH info from the ordinary variant.
pMD = pMD->GetOrdinaryVariant();
}
pMD = pMD->GetOrdinaryVariantIfAsyncVersion();

COR_ILMETHOD* pILHeader;
if (pMD->IsDynamicMethod())
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/jitinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ class CEEInfo : public ICorJitInfo
protected:
COR_ILMETHOD_DECODER* getMethodInfoWorker(
MethodDesc* ftn,
MethodDesc* ilFtn,
COR_ILMETHOD_DECODER* header,
CORINFO_METHOD_INFO* methInfo,
CORINFO_CONTEXT_HANDLE exactContext = NULL);
Expand Down
13 changes: 13 additions & 0 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,19 @@ class MethodDesc
return FindOrCreateAssociatedMethodDesc(this, mt, FALSE, GetMethodInstantiation(), allowInstParam, AsyncVariantLookup::Async, FALSE, FALSE, mt->GetLoadLevel());
}

// If this method supports async version codegen, then get the ordinary non-async method.
// For async version codegen the ordinary non-async method is the method whose IL we use
// for both compilations.
MethodDesc* GetOrdinaryVariantIfAsyncVersion()
{
if (SupportsAsyncVersionCodegen())
{
return GetOrdinaryVariant();
}

return this;
}

// True if a MD is an funny BoxedEntryPointStub (not from the method table) or
// an MD for a generic instantiation...In other words the MethodDescs and the
// MethodTable are guaranteed to be "tightly-knit", i.e. if one is present in
Expand Down
Loading