summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2019-06-11 13:13:09 -0700
committerGitHub <noreply@github.com>2019-06-11 13:13:09 -0700
commit93675fbf467f54ab0f1f5d183c70750c9822c9ca (patch)
tree9fc2f0d0e6507da062ce55f371c46402da2a2f8f
parent118711549ecdc024719d5023a004a2250705cdf9 (diff)
downloadcoreclr-93675fbf467f54ab0f1f5d183c70750c9822c9ca.tar.gz
coreclr-93675fbf467f54ab0f1f5d183c70750c9822c9ca.tar.bz2
coreclr-93675fbf467f54ab0f1f5d183c70750c9822c9ca.zip
R2R ilstubs (#24823)
* Basic support for precompiled pinvoke stubs * Generate R2R file with multiple references to same IL stub (one per method which the IL stub is associated with) * Not all il stubs are p/invokes. Don't fail when they aren't. * Consistently use IsDynamicScope and GetModule to avoid unsafe memory access in IL stub compilation paths * Enable full p/invoke il stubs when compiling System.Private.Corelib * Disable IL Stub generation in crossgen for ARM32. - The cross bitness logic is not correct for IL Stub generation
-rw-r--r--src/inc/corcompile.h5
-rw-r--r--src/vm/compile.cpp114
-rw-r--r--src/vm/compile.h4
-rw-r--r--src/vm/dllimport.cpp30
-rw-r--r--src/vm/ilstubresolver.cpp6
-rw-r--r--src/vm/ilstubresolver.h1
-rw-r--r--src/vm/prestub.cpp52
-rw-r--r--src/vm/stubgen.cpp2
-rw-r--r--src/vm/zapsig.cpp93
-rw-r--r--src/zap/zapinfo.cpp12
-rw-r--r--src/zap/zapreadytorun.cpp38
11 files changed, 313 insertions, 44 deletions
diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h
index 5f39c65f79..755c846f51 100644
--- a/src/inc/corcompile.h
+++ b/src/inc/corcompile.h
@@ -1756,6 +1756,11 @@ class ICorCompileInfo
virtual int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token) = 0;
virtual int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle) = 0;
+
+ virtual BOOL EnumMethodsForStub(CORINFO_METHOD_HANDLE hMethod, void** enumerator) = 0;
+ virtual BOOL EnumNextMethodForStub(void * enumerator, CORINFO_METHOD_HANDLE *hMethod) = 0;
+ virtual void EnumCloseForStubEnumerator(void *enumerator) = 0;
+
#endif
virtual BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName) = 0;
diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp
index f6dd83e99a..321abae729 100644
--- a/src/vm/compile.cpp
+++ b/src/vm/compile.cpp
@@ -69,9 +69,13 @@
#include "versionresilienthashcode.h"
#include "inlinetracking.h"
#include "jithost.h"
+#include "stubgen.h"
#ifdef CROSSGEN_COMPILE
CompilationDomain * theDomain;
+#ifdef FEATURE_READYTORUN_COMPILER
+MapSHash<CORINFO_METHOD_HANDLE, CORINFO_METHOD_HANDLE> s_stubMethodsOfMethod;
+#endif // FEATURE_READYTORUN_COMPILER
#endif
VerboseLevel g_CorCompileVerboseLevel = CORCOMPILE_NO_LOG;
@@ -6192,11 +6196,17 @@ void CEEPreloader::GenerateMethodStubs(
MethodDesc* pMD = GetMethod(hMethod);
MethodDesc* pStubMD = NULL;
- // Do not generate IL stubs when generating ReadyToRun images
+ // Do not generate IL stubs when generating ReadyToRun images except for System.Private.Corelib
// This prevents versionability concerns around IL stubs exposing internal
// implementation details of the CLR.
+ if (IsReadyToRunCompilation() && (!GetAppDomain()->ToCompilationDomain()->GetTargetModule()->IsSystem() || !pMD->IsNDirect()))
+ return;
+
+#if defined(_TARGET_ARM_) && defined(FEATURE_PAL)
+ // Cross-bitness compilation of il stubs does not work. Disable here.
if (IsReadyToRunCompilation())
return;
+#endif // defined(_TARGET_ARM_) && defined(FEATURE_PAL)
DWORD dwNGenStubFlags = NDIRECTSTUB_FL_NGENEDSTUB;
@@ -6285,8 +6295,14 @@ void CEEPreloader::GenerateMethodStubs(
// that we can recover the stub MethodDesc at prestub time, do the fixups, and wire up the native code
if (pStubMD != NULL)
{
- SetStubMethodDescOnInteropMethodDesc(pMD, pStubMD, false /* fReverseStub */);
- pStubMD = NULL;
+#ifdef FEATURE_READYTORUN_COMPILER
+ if (IsReadyToRunCompilation())
+ {
+ s_stubMethodsOfMethod.Add(CORINFO_METHOD_HANDLE(pStubMD), CORINFO_METHOD_HANDLE(pMD));
+ }
+#endif // FEATURE_READYTORUN_COMPILER
+ SetStubMethodDescOnInteropMethodDesc(pMD, pStubMD, false /* fReverseStub */);
+ pStubMD = NULL;
}
}
@@ -6297,6 +6313,10 @@ void CEEPreloader::GenerateMethodStubs(
}
EX_END_CATCH(RethrowTransientExceptions);
+ // Only P/Invoke stubs are eligible to be created in R2R
+ if (IsReadyToRunCompilation())
+ return;
+
//
// Now take care of reverse P/Invoke stubs for delegates
//
@@ -7290,6 +7310,94 @@ HRESULT CompilationDomain::SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths)
return S_OK;
}
+
+#ifdef FEATURE_READYTORUN_COMPILER
+
+class MethodsForStubEnumerator
+{
+ SHash<NoRemoveSHashTraits<MapSHashTraits<CORINFO_METHOD_HANDLE, CORINFO_METHOD_HANDLE>>>::KeyIterator current;
+ SHash<NoRemoveSHashTraits<MapSHashTraits<CORINFO_METHOD_HANDLE, CORINFO_METHOD_HANDLE>>>::KeyIterator end;
+ bool started = false;
+ bool complete = false;
+
+public:
+ MethodsForStubEnumerator(CORINFO_METHOD_HANDLE hMethod) :
+ current(s_stubMethodsOfMethod.Begin(hMethod)),
+ end(s_stubMethodsOfMethod.End(hMethod))
+ {
+ complete = current == end;
+ }
+
+ bool Next()
+ {
+ if (complete)
+ return false;
+
+ if (started)
+ {
+ ++current;
+ }
+ else
+ {
+ started = true;
+ }
+
+ if (current == end)
+ {
+ complete = true;
+ return false;
+ }
+ return true;
+ }
+
+ CORINFO_METHOD_HANDLE Current()
+ {
+ return current->Value();
+ }
+};
+#endif // FEATURE_READYTORUN_COMPILER
+
+BOOL CEECompileInfo::EnumMethodsForStub(CORINFO_METHOD_HANDLE hMethod, void** enumerator)
+{
+#ifdef FEATURE_READYTORUN_COMPILER
+ *enumerator = NULL;
+ if (s_stubMethodsOfMethod.LookupPtr(hMethod) == NULL)
+ return FALSE;
+
+ *enumerator = new MethodsForStubEnumerator(hMethod);
+ return TRUE;
+#else
+ return FALSE;
+#endif // FEATURE_READYTORUN_COMPILER
+}
+
+BOOL CEECompileInfo::EnumNextMethodForStub(void * enumerator, CORINFO_METHOD_HANDLE *hMethod)
+{
+ *hMethod = NULL;
+#ifdef FEATURE_READYTORUN_COMPILER
+ auto stubEnum = (MethodsForStubEnumerator*)enumerator;
+ if (stubEnum->Next())
+ {
+ *hMethod = stubEnum->Current();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+#else
+ return FALSE;
+#endif // FEATURE_READYTORUN_COMPILER
+}
+
+void CEECompileInfo::EnumCloseForStubEnumerator(void *enumerator)
+{
+#ifdef FEATURE_READYTORUN_COMPILER
+ auto stubEnum = (MethodsForStubEnumerator*)enumerator;
+ delete stubEnum;
+#endif // FEATURE_READYTORUN_COMPILER
+}
+
#endif // CROSSGEN_COMPILE
diff --git a/src/vm/compile.h b/src/vm/compile.h
index 8b13af6ecb..d8935c41d1 100644
--- a/src/vm/compile.h
+++ b/src/vm/compile.h
@@ -372,6 +372,10 @@ class CEECompileInfo : public ICorCompileInfo
int GetVersionResilientTypeHashCode(CORINFO_MODULE_HANDLE moduleHandle, mdToken token);
int GetVersionResilientMethodHashCode(CORINFO_METHOD_HANDLE methodHandle);
+
+ BOOL EnumMethodsForStub(CORINFO_METHOD_HANDLE hMethod, void** enumerator);
+ BOOL EnumNextMethodForStub(void * enumerator, CORINFO_METHOD_HANDLE *hMethod);
+ void EnumCloseForStubEnumerator(void *enumerator);
#endif
BOOL HasCustomAttribute(CORINFO_METHOD_HANDLE method, LPCSTR customAttributeName);
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index 469a06e887..aca871d789 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -801,7 +801,7 @@ public:
DWORD dwMethodDescLocalNum = (DWORD)-1;
// Notify the profiler of call out of the runtime
- if (!SF_IsReverseCOMStub(m_dwStubFlags) && (CORProfilerTrackTransitions() || SF_IsNGENedStubForProfiling(m_dwStubFlags)))
+ if (!SF_IsReverseCOMStub(m_dwStubFlags) && (CORProfilerTrackTransitions() || (!IsReadyToRunCompilation() && SF_IsNGENedStubForProfiling(m_dwStubFlags))))
{
dwMethodDescLocalNum = m_slIL.EmitProfilerBeginTransitionCallback(pcsDispatch, m_dwStubFlags);
_ASSERTE(dwMethodDescLocalNum != (DWORD)-1);
@@ -2295,27 +2295,23 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
#endif // FEATURE_COMINTEROP
{
EmitLoadStubContext(pcsEmit, dwStubFlags);
+ // pcsEmit->EmitCALL(METHOD__STUBHELPERS__GET_NDIRECT_TARGET, 1, 1);
+ pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
+ pcsEmit->EmitADD();
+ if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
{
- // Perf: inline the helper for now
- //pcsEmit->EmitCALL(METHOD__STUBHELPERS__GET_NDIRECT_TARGET, 1, 1);
- pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
- pcsEmit->EmitADD();
-
- if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
- {
- pcsEmit->EmitDUP();
- }
+ pcsEmit->EmitDUP();
+ }
- pcsEmit->EmitLDIND_I();
+ pcsEmit->EmitLDIND_I();
- if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
- {
- pcsEmit->EmitADD();
- }
-
- pcsEmit->EmitLDIND_I();
+ if (decltype(NDirectMethodDesc::ndirect.m_pWriteableData)::isRelative)
+ {
+ pcsEmit->EmitADD();
}
+
+ pcsEmit->EmitLDIND_I();
}
#ifdef FEATURE_COMINTEROP
else
diff --git a/src/vm/ilstubresolver.cpp b/src/vm/ilstubresolver.cpp
index 4d429626eb..7f5964b927 100644
--- a/src/vm/ilstubresolver.cpp
+++ b/src/vm/ilstubresolver.cpp
@@ -233,6 +233,11 @@ bool ILStubResolver::IsNativeToCLRInteropStub()
return (m_type == NativeToCLRInteropStub);
}
+bool ILStubResolver::IsCLRToNativeInteropStub()
+{
+ return (m_type == CLRToNativeInteropStub);
+}
+
void ILStubResolver::SetStubType(ILStubType stubType)
{
LIMITED_METHOD_CONTRACT;
@@ -393,7 +398,6 @@ COR_ILMETHOD_SECT_EH* ILStubResolver::AllocEHSect(size_t nClauses)
}
}
-
void ILStubResolver::FreeCompileTimeState()
{
CONTRACTL
diff --git a/src/vm/ilstubresolver.h b/src/vm/ilstubresolver.h
index 8eeb510dbb..6f49398a96 100644
--- a/src/vm/ilstubresolver.h
+++ b/src/vm/ilstubresolver.h
@@ -47,6 +47,7 @@ public:
// ILStubResolver-specific methods
// -----------------------------------
bool IsNativeToCLRInteropStub();
+ bool IsCLRToNativeInteropStub();
MethodDesc* GetStubMethodDesc();
MethodDesc* GetStubTargetMethodDesc();
void SetStubTargetMethodDesc(MethodDesc* pStubTargetMD);
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index d83c419e22..45ee0f02df 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -358,6 +358,20 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig)
return PrepareILBasedCode(pConfig);
}
+bool MayUsePrecompiledILStub()
+{
+ if (g_pConfig->InteropValidatePinnedObjects())
+ return false;
+
+ if (CORProfilerTrackTransitions())
+ return false;
+
+ if (g_pConfig->InteropLogArguments())
+ return false;
+
+ return true;
+}
+
PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)
{
STANDARD_VM_CONTRACT;
@@ -365,7 +379,39 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)
if (pConfig->MayUsePrecompiledCode())
{
- pCode = GetPrecompiledCode(pConfig);
+#ifdef FEATURE_READYTORUN
+ if (this->IsDynamicMethod() && GetLoaderModule()->IsSystem() && MayUsePrecompiledILStub())
+ {
+ DynamicMethodDesc *stubMethodDesc = this->AsDynamicMethodDesc();
+ if (stubMethodDesc->IsILStub() && stubMethodDesc->IsPInvokeStub())
+ {
+ ILStubResolver *pStubResolver = stubMethodDesc->GetILStubResolver();
+ if (pStubResolver->IsCLRToNativeInteropStub())
+ {
+ MethodDesc *pTargetMD = stubMethodDesc->GetILStubResolver()->GetStubTargetMethodDesc();
+ if (pTargetMD != NULL)
+ {
+ pCode = pTargetMD->GetPrecompiledR2RCode(pConfig);
+ if (pCode != NULL)
+ {
+ LOG((LF_ZAP, LL_INFO10000,
+ "ZAP: Using R2R precompiled code" FMT_ADDR " for %s.%s sig=\"%s\" (token %x).\n",
+ DBG_ADDR(pCode),
+ m_pszDebugClassName,
+ m_pszDebugMethodName,
+ m_pszDebugMethodSignature,
+ GetMemberDef()));
+
+ pConfig->SetNativeCode(pCode, &pCode);
+ }
+ }
+ }
+ }
+ }
+#endif // FEATURE_READYTORUN
+
+ if (pCode == NULL)
+ pCode = GetPrecompiledCode(pConfig);
}
if (pCode == NULL)
@@ -412,7 +458,7 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig)
if (pCode != NULL)
{
LOG((LF_ZAP, LL_INFO10000,
- "ZAP: Using R2R precompiled code" FMT_ADDR "for %s.%s sig=\"%s\" (token %x).\n",
+ "ZAP: Using R2R precompiled code" FMT_ADDR " for %s.%s sig=\"%s\" (token %x).\n",
DBG_ADDR(pCode),
m_pszDebugClassName,
m_pszDebugMethodName,
@@ -471,7 +517,7 @@ PCODE MethodDesc::GetPrecompiledNgenCode(PrepareCodeConfig* pConfig)
if (pCode != NULL)
{
LOG((LF_ZAP, LL_INFO10000,
- "ZAP: Using NGEN precompiled code" FMT_ADDR "for %s.%s sig=\"%s\" (token %x).\n",
+ "ZAP: Using NGEN precompiled code " FMT_ADDR " for %s.%s sig=\"%s\" (token %x).\n",
DBG_ADDR(pCode),
m_pszDebugClassName,
m_pszDebugMethodName,
diff --git a/src/vm/stubgen.cpp b/src/vm/stubgen.cpp
index ab054a5c3f..60d1dea340 100644
--- a/src/vm/stubgen.cpp
+++ b/src/vm/stubgen.cpp
@@ -2921,4 +2921,4 @@ void ILCodeStream::ClearCode()
{
LIMITED_METHOD_CONTRACT;
m_uCurInstrIdx = 0;
-}
+} \ No newline at end of file
diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp
index 08d9228c40..125ff7e7bc 100644
--- a/src/vm/zapsig.cpp
+++ b/src/vm/zapsig.cpp
@@ -1324,9 +1324,11 @@ BOOL ZapSig::EncodeMethod(
{
Module * pReferencingModule = pMethod->IsNDirect() ?
pMethod->GetModule() :
- (Module *)pResolvedToken->tokenScope;
+ IsDynamicScope(pResolvedToken->tokenScope) ? NULL: GetModule(pResolvedToken->tokenScope);
- if (!pReferencingModule->IsInCurrentVersionBubble())
+ // pReferencingModule may be NULL if the method is a dynamic method.
+
+ if (pReferencingModule != NULL && !pReferencingModule->IsInCurrentVersionBubble())
{
// FUTURE: Encoding of new cross-module references for ReadyToRun
// This warning is hit for recursive cross-module inlining. It is commented out to avoid noise.
@@ -1334,9 +1336,54 @@ BOOL ZapSig::EncodeMethod(
ThrowHR(E_FAIL);
}
- methodToken = pMethod->IsNDirect() ?
- pMethod->GetMemberDef_NoLogging() :
- pResolvedToken->token;
+ if (pMethod->IsNDirect())
+ {
+ methodToken = pMethod->GetMemberDef_NoLogging();
+ }
+ else if (!IsDynamicScope(pResolvedToken->tokenScope))
+ {
+ // Normal case for IL code
+ methodToken = pResolvedToken->token;
+ }
+ else
+ {
+ // Dynamic scope case. IL Stubs only
+ if (!pMethod->GetModule()->IsSystem())
+ {
+ _ASSERTE(FALSE); // IL stubs are expected to only have references to System.
+ ThrowHR(E_FAIL);
+ }
+
+ if (pInfoModule == pMethod->GetModule())
+ {
+ // This is assuming that the current module being compiled is the same as the module
+ // associated with the method being called. If so, we can identify the method by a MethodDef
+ // token. Otherwise, a more complex operation would be necessary.
+ methodToken = pMethod->GetMemberDef_NoLogging();
+ }
+ else
+ {
+ // Attempt to compile IL stub with use of helper function outside of CoreLib
+ _ASSERTE(FALSE);
+ ThrowHR(E_FAIL);
+ }
+
+ if (!ownerType.IsTypicalTypeDefinition() || pMethod->HasMethodInstantiation())
+ {
+ _ASSERTE(FALSE); // IL Stubs are not expected to have use of generic functions
+ ThrowHR(E_FAIL); // Attempt to compile IL stub with use of generic function. This encoding does not support that.
+ }
+ }
+
+ if (TypeFromToken(methodToken) != mdtMethodDef)
+ {
+ if (pReferencingModule == NULL)
+ {
+ // Invalid situation. Null pReferencingModule can only happen with a dynamic scope,
+ // and in that case the reference can only be a methoddef.
+ ThrowHR(E_FAIL);
+ }
+ }
if (TypeFromToken(methodToken) == mdtMethodSpec)
{
@@ -1447,9 +1494,14 @@ BOOL ZapSig::EncodeMethod(
_ASSERTE(pResolvedToken->cbTypeSpec > 0);
DWORD moduleIndex = MODULE_INDEX_NONE;
- if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope))
+ if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pResolvedToken->tokenScope)))
{
- moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
+ if (IsDynamicScope(pResolvedToken->tokenScope))
+ {
+ _ASSERTE(FALSE); // IL stubs aren't expected to call methods which need this
+ ThrowHR(E_FAIL);
+ }
+ moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) GetModule(pResolvedToken->tokenScope));
}
SigParser sigParser(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
@@ -1492,10 +1544,16 @@ BOOL ZapSig::EncodeMethod(
IfFailThrow(sigParser.GetData(&numGenArgs));
pSigBuilder->AppendData(numGenArgs);
+ if (IsDynamicScope(pResolvedToken->tokenScope))
+ {
+ _ASSERTE(FALSE); // IL stubs aren't expected to call methods which need this
+ ThrowHR(E_FAIL);
+ }
+
DWORD moduleIndex = MODULE_INDEX_NONE;
- if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope))
+ if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pResolvedToken->tokenScope))
{
- moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
+ moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, GetModule(pResolvedToken->tokenScope));
}
while (numGenArgs != 0)
@@ -1531,9 +1589,14 @@ BOOL ZapSig::EncodeMethod(
_ASSERTE(pConstrainedResolvedToken->cbTypeSpec > 0);
DWORD moduleIndex = MODULE_INDEX_NONE;
- if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pConstrainedResolvedToken->tokenScope)
+ if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pConstrainedResolvedToken->tokenScope))
{
- moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pConstrainedResolvedToken->tokenScope);
+ if (IsDynamicScope(pConstrainedResolvedToken->tokenScope))
+ {
+ _ASSERTE(FALSE); // IL stubs aren't expected to call methods which need this
+ ThrowHR(E_FAIL);
+ }
+ moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, GetModule(pConstrainedResolvedToken->tokenScope));
}
SigParser sigParser(pConstrainedResolvedToken->pTypeSpec, pConstrainedResolvedToken->cbTypeSpec);
@@ -1584,7 +1647,13 @@ void ZapSig::EncodeField(
// Encode the referencing field type
pMT = (MethodTable *)(pResolvedToken->hClass);
- Module * pReferencingModule = (Module *)pResolvedToken->tokenScope;
+ if (IsDynamicScope(pResolvedToken->tokenScope))
+ {
+ _ASSERTE(FALSE); // IL stubs aren't expected to need to access this sort of field
+ ThrowHR(E_FAIL);
+ }
+
+ Module * pReferencingModule = GetModule(pResolvedToken->tokenScope);
if (!pReferencingModule->IsInCurrentVersionBubble())
{
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index f57556b830..007765b3ab 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -2228,6 +2228,18 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken,
}
else
{
+ if (pResult->methodFlags & CORINFO_FLG_INTRINSIC)
+ {
+ bool unused;
+ CorInfoIntrinsics intrinsic = getIntrinsicID(pResult->hMethod, &unused);
+ if ((intrinsic == CORINFO_INTRINSIC_StubHelpers_GetStubContext)
+ || (intrinsic == CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr)
+ )
+ {
+ // These intrinsics are always expanded directly in the jit and do not correspond to external methods
+ return;
+ }
+ }
pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken);
}
diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp
index cb41a1a4d7..73670bdc16 100644
--- a/src/zap/zapreadytorun.cpp
+++ b/src/zap/zapreadytorun.cpp
@@ -222,12 +222,6 @@ void ZapImage::OutputEntrypointsTableForReadyToRun()
{
ZapMethodHeader * pMethod = m_MethodCompilationOrder[i];
- mdMethodDef token = GetJitInfo()->getMethodDefFromMethod(pMethod->GetHandle());
- CORINFO_SIG_INFO sig;
- GetJitInfo()->getMethodSig(pMethod->GetHandle(), &sig);
-
- int rid = RidFromToken(token);
- _ASSERTE(rid != 0);
BlobVertex * pFixupBlob = NULL;
@@ -250,8 +244,16 @@ void ZapImage::OutputEntrypointsTableForReadyToRun()
}
}
+ CORINFO_SIG_INFO sig;
+ GetJitInfo()->getMethodSig(pMethod->GetHandle(), &sig);
+
+ mdMethodDef token = GetJitInfo()->getMethodDefFromMethod(pMethod->GetHandle());
+ int rid = RidFromToken(token);
+
if (sig.sigInst.classInstCount > 0 || sig.sigInst.methInstCount > 0)
{
+ _ASSERTE(rid != 0);
+
CORINFO_MODULE_HANDLE module = GetJitInfo()->getClassModule(pMethod->GetClassHandle());
_ASSERTE(GetCompileInfo()->IsInCurrentVersionBubble(module));
SigBuilder sigBuilder;
@@ -273,7 +275,29 @@ void ZapImage::OutputEntrypointsTableForReadyToRun()
}
else
{
- vertexArray.Set(rid - 1, new (GetHeap()) EntryPointVertex(pMethod->GetMethodIndex(), pFixupBlob));
+ int rid = RidFromToken(token);
+ if (rid != 0)
+ {
+ vertexArray.Set(rid - 1, new (GetHeap()) EntryPointVertex(pMethod->GetMethodIndex(), pFixupBlob));
+ }
+ else
+ {
+ // This is a p/invoke stub, get the list of methods associated with the stub, and put this code in that set of rids
+ void *targetMethodEnum;
+ BOOL isStubWithTargetMethods = GetCompileInfo()->EnumMethodsForStub(pMethod->GetHandle(), &targetMethodEnum);
+ _ASSERTE(isStubWithTargetMethods);
+
+ CORINFO_METHOD_HANDLE hTargetMethod;
+ while (GetCompileInfo()->EnumNextMethodForStub(targetMethodEnum, &hTargetMethod))
+ {
+ mdMethodDef token = GetJitInfo()->getMethodDefFromMethod(hTargetMethod);
+ int rid = RidFromToken(token);
+ _ASSERTE(rid != 0);
+ vertexArray.Set(rid - 1, new (GetHeap()) EntryPointVertex(pMethod->GetMethodIndex(), pFixupBlob));
+ }
+
+ GetCompileInfo()->EnumCloseForStubEnumerator(targetMethodEnum);
+ }
}
fEmpty = false;