@@ -104,6 +104,33 @@ static CallStubHeader *UpdateCallStubForMethod(MethodDesc *pMD, PCODE target)
104104 return header;
105105}
106106
107+ MethodDesc* GetTargetPInvokeMethodDesc (PCODE target)
108+ {
109+ CONTRACTL
110+ {
111+ THROWS;
112+ MODE_ANY;
113+ PRECONDITION (CheckPointer ((void *)target));
114+ }
115+ CONTRACTL_END
116+
117+ GCX_PREEMP ();
118+
119+ RangeSection * pRS = ExecutionManager::FindCodeRange (target, ExecutionManager::GetScanFlags ());
120+ if (pRS != NULL && pRS->_flags & RangeSection::RANGE_SECTION_RANGELIST)
121+ {
122+ if (pRS->_pRangeList ->GetCodeBlockKind () == STUB_CODE_BLOCK_STUBPRECODE)
123+ {
124+ if (((StubPrecode*)target)->GetType () == PRECODE_PINVOKE_IMPORT)
125+ {
126+ return dac_cast<PTR_MethodDesc>(((PInvokeImportPrecode*)target)->GetMethodDesc ());
127+ }
128+ }
129+ }
130+
131+ return NULL ;
132+ }
133+
107134void InvokeManagedMethod (MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target)
108135{
109136 CONTRACTL
@@ -124,7 +151,22 @@ void InvokeManagedMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE tar
124151
125152 if (target != (PCODE)NULL )
126153 {
127- _ASSERTE (pHeader->GetTarget () == target);
154+ PCODE headerTarget = pHeader->GetTarget ();
155+ if (target != headerTarget)
156+ {
157+ #ifdef DEBUG
158+ // For pinvokes we may have a PInvokeImportPrecode as a pointer, and need to use passed in target preferentially
159+ // Since on multiple threads we may be racing to use this method, it is possible that the current target could be
160+ // the PInvokeImportPrecode or the actual target method, so we should allow either of them to match.
161+ MethodDesc *pMDTarget = GetTargetPInvokeMethodDesc (target);
162+ MethodDesc *pMDHeaderTarget = GetTargetPInvokeMethodDesc (headerTarget);
163+
164+ _ASSERTE (pMDTarget == NULL || pMDHeaderTarget == NULL );
165+ _ASSERTE (pMDTarget == NULL || pMDTarget == pMD);
166+ _ASSERTE (pMDHeaderTarget == NULL || pMDHeaderTarget == pMD);
167+ #endif // DEBUG
168+ pHeader->SetTarget (target);
169+ }
128170 }
129171
130172 pHeader->Invoke (pHeader->Routines , pArgs, pRet, pHeader->TotalStackSize );
0 commit comments