This commit is contained in:
Aaron Robinson 2025-07-30 07:08:10 -07:00 committed by GitHub
commit 796f6534a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 57 deletions

View File

@ -219,7 +219,7 @@ public:
virtual void MarshalLCID(int argIdx) = 0;
virtual void MarshalField(MarshalInfo* pInfo, UINT32 managedOffset, UINT32 nativeOffset, FieldDesc* pFieldDesc) = 0;
virtual void EmitInvokeTarget(MethodDesc *pStubMD) = 0;
virtual void EmitInvokeTarget(MethodDesc* pTargetMD, MethodDesc* pStubMD) = 0;
virtual void FinishEmit(MethodDesc* pMD) = 0;
@ -489,11 +489,11 @@ public:
pStubMD->AsDynamicMethodDesc()->SetStoredMethodSig(pNewSig, cbNewSig);
}
void EmitInvokeTarget(MethodDesc *pStubMD)
void EmitInvokeTarget(MethodDesc* pTargetMD, MethodDesc* pStubMD)
{
STANDARD_VM_CONTRACT;
m_slIL.DoNDirect(m_slIL.GetDispatchCodeStream(), m_dwStubFlags, pStubMD);
m_slIL.DoNDirect(m_slIL.GetDispatchCodeStream(), m_dwStubFlags, pTargetMD);
}
virtual void EmitExceptionHandler(LocalDesc* pNativeReturnType, LocalDesc* pManagedReturnType,
@ -709,7 +709,7 @@ public:
}
// Invoke the target (calli, call method, call delegate, get/set field, etc.)
EmitInvokeTarget(pStubMD);
EmitInvokeTarget(m_slIL.GetTargetMD(), pStubMD);
// Saving last error must be the first thing we do after returning from the target
if (m_fSetLastError && SF_IsForwardStub(m_dwStubFlags))
@ -808,13 +808,17 @@ public:
}
else if (SF_IsStructMarshalStub(m_dwStubFlags))
{
// Struct marshal stubs don't actually call anything so they do not need the secrect parameter.
// Struct marshal stubs don't actually call anything so they do not need the secret parameter.
}
else if (SF_IsForwardDelegateStub(m_dwStubFlags))
{
// Forward delegate stubs get all the context they need in 'this' so they
// don't use the secret parameter.
}
else if (SF_IsForwardPInvokeStub(m_dwStubFlags))
{
// Forward stubs (i.e., NDirects) don't use the secret parameter
}
else
{
// All other IL stubs will need to use the secret parameter.
@ -1559,7 +1563,7 @@ public:
m_pFD = pFD;
}
void EmitInvokeTarget(MethodDesc *pStubMD)
void EmitInvokeTarget(MethodDesc* pTargetMD, MethodDesc* pStubMD)
{
STANDARD_VM_CONTRACT;
@ -2084,7 +2088,7 @@ void NDirectStubLinker::End(DWORD dwStubFlags)
}
}
void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD)
void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc* pMD)
{
STANDARD_VM_CONTRACT;
@ -2121,10 +2125,10 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
if (!SF_IsCOMStub(dwStubFlags)) // forward P/Invoke
#endif // FEATURE_COMINTEROP
{
EmitLoadStubContext(pcsEmit, dwStubFlags);
pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pNDirectTarget));
pcsEmit->EmitADD();
_ASSERTE(pMD->IsNDirect());
NDirectMethodDesc* pTargetMD = (NDirectMethodDesc*)pMD;
pcsEmit->EmitLDC((DWORD_PTR)&pTargetMD->ndirect.m_pNDirectTarget);
pcsEmit->EmitCONV_I();
pcsEmit->EmitLDIND_I();
}
#ifdef FEATURE_COMINTEROP
@ -2427,7 +2431,7 @@ public:
}
#endif // FEATURE_COMINTEROP
void EmitInvokeTarget(MethodDesc *pStubMD)
void EmitInvokeTarget(MethodDesc* pTargetMD, MethodDesc* pStubMD)
{
LIMITED_METHOD_CONTRACT;
UNREACHABLE_MSG("Should never come to DispatchStubState::EmitInvokeTarget");

View File

@ -251,6 +251,17 @@ inline bool SF_IsCOMEventCallStub (DWORD dwStubFlags) { LIMITED_METHOD_CONT
inline bool SF_IsFieldGetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_FIELDGETTER)); }
inline bool SF_IsFieldSetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_FIELDSETTER)); }
inline bool SF_IsForwardStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return !SF_IsReverseStub(dwStubFlags); }
inline bool SF_IsForwardPInvokeStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (!SF_IsCOMStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReversePInvokeStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (!SF_IsCOMStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
inline bool SF_IsForwardCOMStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsCOMStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReverseCOMStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsCOMStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
inline bool SF_IsForwardDelegateStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsDelegateStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReverseDelegateStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsDelegateStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
inline bool SF_IsSharedStub(DWORD dwStubFlags)
{
WRAPPER_NO_CONTRACT;
@ -270,20 +281,14 @@ inline bool SF_IsSharedStub(DWORD dwStubFlags)
return false;
}
if (SF_IsForwardPInvokeStub(dwStubFlags))
{
return false;
}
return true;
}
inline bool SF_IsForwardStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return !SF_IsReverseStub(dwStubFlags); }
inline bool SF_IsForwardPInvokeStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (!SF_IsCOMStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReversePInvokeStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (!SF_IsCOMStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
inline bool SF_IsForwardCOMStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsCOMStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReverseCOMStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsCOMStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
inline bool SF_IsForwardDelegateStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsDelegateStub(dwStubFlags) && SF_IsForwardStub(dwStubFlags)); }
inline bool SF_IsReverseDelegateStub (DWORD dwStubFlags) { WRAPPER_NO_CONTRACT; return (SF_IsDelegateStub(dwStubFlags) && SF_IsReverseStub(dwStubFlags)); }
#undef COM_ONLY
inline void SF_ConsistencyCheck(DWORD dwStubFlags)
@ -476,7 +481,7 @@ public:
void Begin(DWORD dwStubFlags);
void End(DWORD dwStubFlags);
void DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD);
void DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc* pMD);
void EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwPinnedLocal);
void LoadCleanupWorkList(ILCodeStream* pcsEmit);
#ifdef PROFILING_SUPPORTED

View File

@ -2476,20 +2476,19 @@ MethodImpl *MethodDesc::GetMethodImpl()
#ifndef DACCESS_COMPILE
//*******************************************************************************
BOOL MethodDesc::RequiresMethodDescCallingConvention(BOOL fEstimateForChunk /*=FALSE*/)
BOOL MethodDesc::RequiresMethodDescCallingConvention()
{
LIMITED_METHOD_CONTRACT;
// Interop marshaling is implemented using shared stubs
if (IsNDirect() || IsCLRToCOMCall())
if (IsCLRToCOMCall())
return TRUE;
return FALSE;
}
//*******************************************************************************
BOOL MethodDesc::RequiresStableEntryPoint(BOOL fEstimateForChunk /*=FALSE*/)
BOOL MethodDesc::RequiresStableEntryPoint()
{
BYTE bFlags4 = VolatileLoadWithoutBarrier(&m_bFlags4);
if (bFlags4 & enum_flag4_ComputedRequiresStableEntryPoint)
@ -2498,16 +2497,14 @@ BOOL MethodDesc::RequiresStableEntryPoint(BOOL fEstimateForChunk /*=FALSE*/)
}
else
{
if (fEstimateForChunk)
return RequiresStableEntryPointCore(fEstimateForChunk);
BOOL fRequiresStableEntryPoint = RequiresStableEntryPointCore(FALSE);
BOOL fRequiresStableEntryPoint = RequiresStableEntryPointCore();
BYTE requiresStableEntrypointFlags = (BYTE)(enum_flag4_ComputedRequiresStableEntryPoint | (fRequiresStableEntryPoint ? enum_flag4_RequiresStableEntryPoint : 0));
InterlockedUpdateFlags4(requiresStableEntrypointFlags, TRUE);
return fRequiresStableEntryPoint;
}
}
BOOL MethodDesc::RequiresStableEntryPointCore(BOOL fEstimateForChunk)
BOOL MethodDesc::RequiresStableEntryPointCore()
{
LIMITED_METHOD_CONTRACT;
@ -2523,26 +2520,17 @@ BOOL MethodDesc::RequiresStableEntryPointCore(BOOL fEstimateForChunk)
if (IsLCGMethod())
return TRUE;
if (fEstimateForChunk)
{
// Make a best guess based on the method table of the chunk.
if (IsInterface())
return TRUE;
}
else
{
// Wrapper stubs are stored in generic dictionary that's not backpatched
if (IsWrapperStub())
return TRUE;
// Wrapper stubs are stored in generic dictionary that's not backpatched
if (IsWrapperStub())
return TRUE;
// TODO: Can we avoid early allocation of precodes for interfaces and cominterop?
if ((IsInterface() && !IsStatic() && IsVirtual()) || IsCLRToCOMCall())
return TRUE;
// TODO: Can we avoid early allocation of precodes for interfaces and cominterop?
if ((IsInterface() && !IsStatic() && IsVirtual()) || IsCLRToCOMCall())
return TRUE;
// FCalls need stable entrypoint that can be mapped back to MethodDesc
if (IsFCall())
return TRUE;
}
// FCalls need stable entrypoint that can be mapped back to MethodDesc
if (IsFCall())
return TRUE;
return FALSE;
}

View File

@ -1709,14 +1709,13 @@ public:
// Running the Prestub preparation step.
// The stub produced by prestub requires method desc to be passed
// in dedicated register. Used to implement stubs shared between
// MethodDescs (e.g. PInvoke stubs)
BOOL RequiresMethodDescCallingConvention(BOOL fEstimateForChunk = FALSE);
// in dedicated register.
BOOL RequiresMethodDescCallingConvention();
// Returns true if the method has to have stable entrypoint always.
BOOL RequiresStableEntryPoint(BOOL fEstimateForChunk = FALSE);
BOOL RequiresStableEntryPoint();
private:
BOOL RequiresStableEntryPointCore(BOOL fEstimateForChunk);
BOOL RequiresStableEntryPointCore();
public:
//
@ -2900,7 +2899,7 @@ public:
bool HasMDContextArg() const
{
LIMITED_METHOD_CONTRACT;
return IsCLRToCOMStub() || (IsPInvokeStub() && !HasFlags(FlagIsDelegate));
return IsCLRToCOMStub();
}
//

View File

@ -2988,11 +2988,11 @@ BOOL StackFrameIterator::CheckForSkippedFrames(void)
(dac_cast<TADDR>(m_crawl.pFrame) < pvReferenceSP)
)
{
BOOL fReportInteropMD =
// If we see InlinedCallFrame in certain IL stubs, we should report the MD that
// was passed to the stub as its secret argument. This is the true interop MD.
// Note that code:InlinedCallFrame.GetFunction may return NULL in this case because
// the call is made using the CALLI instruction.
BOOL fReportInteropMD =
m_crawl.pFrame != FRAME_TOP &&
m_crawl.pFrame->GetFrameIdentifier() == FrameIdentifier::InlinedCallFrame &&
m_crawl.pFunc != NULL &&