summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2018-06-19 05:58:44 -0700
committerGitHub <noreply@github.com>2018-06-19 05:58:44 -0700
commit10111af6ba5e18f4a9b9c6eb80d49ed545604cfa (patch)
tree83b8f6dd6f8604165d2856a14008d11c6bb3119a
parent57375e5cd91b3554e0e9690bba56d7fc341f8ce7 (diff)
downloadcoreclr-10111af6ba5e18f4a9b9c6eb80d49ed545604cfa.tar.gz
coreclr-10111af6ba5e18f4a9b9c6eb80d49ed545604cfa.tar.bz2
coreclr-10111af6ba5e18f4a9b9c6eb80d49ed545604cfa.zip
PInvoke calli support for CoreRT (#18534)
* Ifdef out NGen-specific PInvoke calli inlining limitation for CoreCLR This limitation seems to be a left-over from effort to eliminate JITing with fragile NGen. * Delete dead partial-trust related code * Allow PInvoke stub inlining * Add convertCalliToCall JIT/EE interface method * Update superpmi
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h2
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp35
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h5
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp8
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp5
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp6
-rw-r--r--src/inc/corinfo.h16
-rw-r--r--src/jit/flowgraph.cpp2
-rw-r--r--src/jit/importer.cpp81
-rw-r--r--src/jit/inline.def1
-rw-r--r--src/vm/jitinterface.cpp5
-rw-r--r--src/vm/jitinterface.h3
-rw-r--r--src/zap/zapinfo.cpp7
-rw-r--r--src/zap/zapinfo.h4
16 files changed, 135 insertions, 52 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
index 61d1785b51..6645626c24 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -906,6 +906,8 @@ void MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd);
// return a thunk that will copy the arguments for the given signature.
void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags);
+bool convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert);
+
// return memory manager that the JIT can use to allocate a regular memory
IEEMemoryManager* getMemoryManager();
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index 6a8b77e246..df9f43587a 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -35,6 +35,7 @@ LWM(CompareTypesForCast, DLDL, DWORD)
LWM(CompareTypesForEquality, DLDL, DWORD)
LWM(CompileMethod, DWORD, Agnostic_CompileMethod)
LWM(ConstructStringLiteral, DLD, DLD)
+LWM(ConvertPInvokeCalliToCall, DLD, DWORDLONG)
LWM(EmbedClassHandle, DWORDLONG, DLDL)
LWM(EmbedFieldHandle, DWORDLONG, DLDL)
LWM(EmbedGenericHandle, Agnostic_EmbedGenericHandle, Agnostic_CORINFO_GENERICHANDLE_RESULT)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index aa806c31df..b5de52feaf 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -2436,6 +2436,41 @@ InfoAccessType MethodContext::repConstructStringLiteral(CORINFO_MODULE_HANDLE mo
return (InfoAccessType)temp2.B;
}
+void MethodContext::recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert, bool result)
+{
+ if (ConvertPInvokeCalliToCall == nullptr)
+ ConvertPInvokeCalliToCall = new LightWeightMap<DLD, DWORDLONG>();
+
+ DLD key;
+ ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero
+ // out padding too
+ key.A = (DWORDLONG)pResolvedToken->tokenScope;
+ key.B = (DWORD)pResolvedToken->token;
+
+ DWORDLONG value = (DWORDLONG)(result ? pResolvedToken->hMethod : 0);
+
+ ConvertPInvokeCalliToCall->Add(key, value);
+ DEBUG_REC(dmpConvertPInvokeCalliToCall(key, value));
+}
+void MethodContext::dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value)
+{
+ printf("ConvertPInvokeCalliToCall key mod-%016llX tok-%08X, value %016llX", key.A, key.B, value);
+}
+bool MethodContext::repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ DLD key;
+ ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero
+ // out padding too
+ key.A = (DWORDLONG)pResolvedToken->tokenScope;
+ key.B = (DWORD)pResolvedToken->token;
+
+ DWORDLONG value = ConvertPInvokeCalliToCall->Get(key);
+ DEBUG_REP(dmpGetArgType(key, value));
+
+ pResolvedToken->hMethod = (CORINFO_METHOD_HANDLE)value;
+ return value != 0;
+}
+
void MethodContext::recEmptyStringLiteral(void** pValue, InfoAccessType result)
{
if (EmptyStringLiteral == nullptr)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index b7f19a345a..ac7acf1ea1 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -805,6 +805,10 @@ public:
void dmpConstructStringLiteral(DLD key, DLD value);
InfoAccessType repConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue);
+ void recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert, bool result);
+ void dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value);
+ bool repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert);
+
void recEmptyStringLiteral(void** ppValue, InfoAccessType result);
void dmpEmptyStringLiteral(DWORD key, DLD value);
InfoAccessType repEmptyStringLiteral(void** ppValue);
@@ -1311,6 +1315,7 @@ enum mcPackets
Packet_CompareTypesForEquality = 164, // Added 10/4/17
Packet_CompileMethod = 143, // retired as 141 on 2013/07/09
Packet_ConstructStringLiteral = 15,
+ Packet_ConvertPInvokeCalliToCall = 169, // Added 4/29/18
Packet_EmbedClassHandle = 16,
Packet_EmbedFieldHandle = 17,
Packet_EmbedGenericHandle = 18,
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index d63a8acb90..5d70a5488f 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -1825,6 +1825,14 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
return temp;
}
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ mc->cr->AddCall("convertPInvokeCalliToCall");
+ bool result = original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
+ mc->recConvertPInvokeCalliToCall(pResolvedToken, fMustConvert, result);
+ return result;
+}
+
InfoAccessType interceptor_ICJI::emptyStringLiteral(void** ppValue)
{
mc->cr->AddCall("emptyStringLiteral");
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 1b18072f41..316fd8c1ed 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -1412,6 +1412,12 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
return original_ICorJitInfo->constructStringLiteral(module, metaTok, ppValue);
}
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ mcs->AddCall("convertPInvokeCalliToCall");
+ return original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
+}
+
InfoAccessType interceptor_ICJI::emptyStringLiteral(void** ppValue)
{
mcs->AddCall("emptyStringLiteral");
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index ac7a6d9f30..97c434755e 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -1266,6 +1266,11 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
return original_ICorJitInfo->constructStringLiteral(module, metaTok, ppValue);
}
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ return original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
+}
+
InfoAccessType interceptor_ICJI::emptyStringLiteral(void** ppValue)
{
return original_ICorJitInfo->emptyStringLiteral(ppValue);
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index 852b1147e6..43ac5a8502 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -1580,6 +1580,12 @@ void* MyICJI::getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTail
return jitInstance->mc->repGetTailCallCopyArgsThunk(pSig, flags);
}
+bool MyICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ jitInstance->mc->cr->AddCall("convertPInvokeCalliToCall");
+ return jitInstance->mc->repConvertPInvokeCalliToCall(pResolvedToken, fMustConvert);
+}
+
// Stuff directly on ICorJitInfo
// Returns extended flags for a particular compilation instance.
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index d430412f3b..1e4bb96184 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use
#define SELECTANY extern __declspec(selectany)
#endif
-SELECTANY const GUID JITEEVersionIdentifier = { /* 0ba106c8-81a0-407f-99a1-928448c1eb62 */
- 0x0ba106c8,
- 0x81a0,
- 0x407f,
- {0x99, 0xa1, 0x92, 0x84, 0x48, 0xc1, 0xeb, 0x62}
+SELECTANY const GUID JITEEVersionIdentifier = { /* dc72a60f-22f2-49fb-809f-00077f3eb1a8 */
+ 0xdc72a60f,
+ 0x22f2,
+ 0x49fb,
+ { 0x80, 0x9f, 0x0, 0x7, 0x7f, 0x3e, 0xb1, 0xa8}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -3153,6 +3153,12 @@ public:
CORINFO_SIG_INFO *pSig,
CorInfoHelperTailCallSpecialHandling flags
) = 0;
+
+ // Optionally, convert calli to regular method call. This is for PInvoke argument marshalling.
+ virtual bool convertPInvokeCalliToCall(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ bool fMustConvert
+ ) = 0;
};
/**********************************************************************************/
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index df05fa4fd3..fb35965b3d 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -4752,6 +4752,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
}
break;
+#if !defined(FEATURE_CORECLR)
case CEE_CALLI:
// CEE_CALLI should not be inlined if the call indirect target has a calling convention other than
@@ -4784,6 +4785,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
}
}
break;
+#endif // FEATURE_CORECLR
case CEE_JMP:
retBlocks++;
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index af21deaaed..b236c97507 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -4753,7 +4753,7 @@ bool Compiler::verCheckTailCallConstraint(
if (opcode == CEE_CALLI)
{
/* Get the call sig */
- eeGetSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, &sig);
+ eeGetSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, &sig);
// We don't know the target method, so we have to infer the flags, or
// assume the worst-case.
@@ -4781,7 +4781,7 @@ bool Compiler::verCheckTailCallConstraint(
if ((sig.callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG)
{
- eeGetCallSiteSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, &sig);
+ eeGetCallSiteSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, &sig);
}
// check compatibility of the arguments
@@ -4849,7 +4849,7 @@ bool Compiler::verCheckTailCallConstraint(
if (methodClassFlgs & CORINFO_FLG_ARRAY)
{
assert(opcode != CEE_CALLI);
- eeGetCallSiteSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, &sig);
+ eeGetCallSiteSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, &sig);
}
}
@@ -6097,8 +6097,11 @@ void Compiler::impCheckForPInvokeCall(
}
optNativeCallCount++;
- if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) && methHnd == nullptr)
+ if (methHnd == nullptr && (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) || IsTargetAbi(CORINFO_CORERT_ABI)))
{
+ // PInvoke in CoreRT ABI must be always inlined. Non-inlineable CALLI cases have been
+ // converted to regular method calls earlier using convertPInvokeCalliToCall.
+
// PInvoke CALLI in IL stubs must be inlined
}
else
@@ -6967,8 +6970,19 @@ var_types Compiler::impImportCall(OPCODE opcode,
if (opcode == CEE_CALLI)
{
+ if (IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ // See comment in impCheckForPInvokeCall
+ BasicBlock* block = compIsForInlining() ? impInlineInfo->iciBlock : compCurBB;
+ if (info.compCompHnd->convertPInvokeCalliToCall(pResolvedToken, !impCanPInvokeInlineCallSite(block)))
+ {
+ eeGetCallInfo(pResolvedToken, nullptr, CORINFO_CALLINFO_ALLOWINSTPARAM, callInfo);
+ return impImportCall(CEE_CALL, pResolvedToken, nullptr, nullptr, prefixFlags, callInfo, rawILOffset);
+ }
+ }
+
/* Get the call site sig */
- eeGetSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, &calliSig);
+ eeGetSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, &calliSig);
callRetTyp = JITtype2varType(calliSig.retType);
@@ -7532,7 +7546,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
#ifdef DEBUG
unsigned numArgsDef = sig->numArgs;
#endif
- eeGetCallSiteSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, sig);
+ eeGetCallSiteSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, sig);
#ifdef DEBUG
// We cannot lazily obtain the signature of a vararg call because using its method
@@ -13317,7 +13331,9 @@ void Compiler::impImportBlockCode(BasicBlock* block)
memset(&resolvedToken, 0, sizeof(resolvedToken));
memset(&callInfo, 0, sizeof(callInfo));
- resolvedToken.token = getU4LittleEndian(codeAddr);
+ resolvedToken.token = getU4LittleEndian(codeAddr);
+ resolvedToken.tokenContext = impTokenLookupContextHandle;
+ resolvedToken.tokenScope = info.compScopeHnd;
}
CALL: // memberRef should be set.
@@ -13416,31 +13432,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// For delegates, this is the call to the delegate constructor, not the access check on the
// LD(virt)FTN.
impHandleAccessAllowed(callInfo.accessAllowed, &callInfo.callsiteCalloutHelper);
-
-#if 0 // DevDiv 410397 - This breaks too many obfuscated apps to do this in an in-place release
-
- // DevDiv 291703 - we need to check for accessibility between the caller of InitializeArray
- // and the field it is reading, thus it is now unverifiable to not immediately precede with
- // ldtoken <filed token>, and we now check accessibility
- if ((callInfo.methodFlags & CORINFO_FLG_INTRINSIC) &&
- (info.compCompHnd->getIntrinsicID(callInfo.hMethod) == CORINFO_INTRINSIC_InitializeArray))
- {
- if (prevOpcode != CEE_LDTOKEN)
- {
- Verify(prevOpcode == CEE_LDTOKEN, "Need ldtoken for InitializeArray");
- }
- else
- {
- assert(lastLoadToken != NULL);
- // Now that we know we have a token, verify that it is accessible for loading
- CORINFO_RESOLVED_TOKEN resolvedLoadField;
- impResolveToken(lastLoadToken, &resolvedLoadField, CORINFO_TOKENKIND_Field);
- eeGetFieldInfo(&resolvedLoadField, CORINFO_ACCESS_INIT_ARRAY, &fieldInfo);
- impHandleAccessAllowed(fieldInfo.accessAllowed, &fieldInfo.accessCalloutHelper);
- }
- }
-
-#endif // DevDiv 410397
}
if (tiVerificationNeeded)
@@ -13450,21 +13441,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
&callInfo DEBUGARG(info.compFullName));
}
- // Insert delegate callout here.
- if (opcode == CEE_NEWOBJ && (mflags & CORINFO_FLG_CONSTRUCTOR) && (clsFlags & CORINFO_FLG_DELEGATE))
- {
-#ifdef DEBUG
- // We should do this only if verification is enabled
- // If verification is disabled, delegateCreateStart will not be initialized correctly
- if (tiVerificationNeeded)
- {
- mdMemberRef delegateMethodRef = mdMemberRefNil;
- // We should get here only for well formed delegate creation.
- assert(verCheckDelegateCreation(delegateCreateStart, codeAddr - 1, delegateMethodRef));
- }
-#endif
- }
-
callTyp = impImportCall(opcode, &resolvedToken, constraintCall ? &constrainedResolvedToken : nullptr,
newObjThisPtr, prefixFlags, &callInfo, opcodeOffs);
if (compDonotInline())
@@ -19081,6 +19057,17 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode,
return;
}
+ /* Check legality of PInvoke callsite (for inlining of marshalling code) */
+
+ if (methAttr & CORINFO_FLG_PINVOKE)
+ {
+ if (!impCanPInvokeInlineCallSite(compCurBB))
+ {
+ inlineResult.NoteFatal(InlineObservation::CALLSITE_PINVOKE_EH);
+ return;
+ }
+ }
+
InlineCandidateInfo* inlineCandidateInfo = nullptr;
impCheckCanInline(call, fncHandle, methAttr, exactContextHnd, &inlineCandidateInfo, &inlineResult);
diff --git a/src/jit/inline.def b/src/jit/inline.def
index 4dd67402fb..2594c072d4 100644
--- a/src/jit/inline.def
+++ b/src/jit/inline.def
@@ -159,6 +159,7 @@ INLINE_OBSERVATION(REQUIRES_SAME_THIS, bool, "requires same this",
INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch", FATAL, CALLSITE)
INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLSITE)
INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals", FATAL, CALLSITE)
+INLINE_OBSERVATION(PINVOKE_EH, bool, "PInvoke call site with EH", FATAL, CALLSITE)
// ------ Call Site Performance -------
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 0a921e56fa..367dfb091a 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -13746,6 +13746,11 @@ void* CEEInfo::getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig,
return ftn;
}
+bool CEEInfo::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+{
+ return false;
+}
+
void CEEInfo::allocMem (
ULONG hotCodeSize, /* IN */
ULONG coldCodeSize, /* IN */
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index 1e4c847204..ebe64edbb9 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -950,6 +950,9 @@ public:
void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig,
CorInfoHelperTailCallSpecialHandling flags);
+ bool convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ bool fMustConvert);
+
void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */
CORINFO_CONST_LOOKUP * pResult, /* OUT */
CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index 725a326e06..634a63e331 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -1690,6 +1690,13 @@ void* ZapInfo::getTailCallCopyArgsThunk (
return m_pImage->GetWrappers()->GetStub(pStub);
}
+bool ZapInfo::convertPInvokeCalliToCall(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ bool fMustConvert)
+{
+ return false;
+}
+
#ifdef FEATURE_READYTORUN_COMPILER
ReadyToRunHelper MapReadyToRunHelper(CorInfoHelpFunc func, bool * pfOptimizeForSize)
{
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index 0e2bf9dcaf..8b5ad1d4e8 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -360,6 +360,10 @@ public:
CORINFO_SIG_INFO *pSig,
CorInfoHelperTailCallSpecialHandling flags);
+ bool convertPInvokeCalliToCall(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ bool fMustConvert);
+
void getFunctionEntryPoint(
CORINFO_METHOD_HANDLE ftn, /* IN */
CORINFO_CONST_LOOKUP * pResult, /* OUT */