diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 485a0c336156d8..0760f6407b8787 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -7514,6 +7514,7 @@ static bool getILIntrinsicImplementationForActivator(MethodDesc* ftn, // COR_ILMETHOD_DECODER* CEEInfo::getMethodInfoWorker( MethodDesc* ftn, + MethodDesc* ilFtn, COR_ILMETHOD_DECODER* header, CORINFO_METHOD_INFO* methInfo, CORINFO_CONTEXT_HANDLE exactContext) @@ -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; @@ -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()) { // 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; } @@ -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; @@ -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 @@ -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()) diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index aebb381a0bf37d..f35fb0a1d67986 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -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); diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 4ef12cda32dff0..e38d8b2ed9f4fc 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -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