Skip to content

Commit

Permalink
Convert profiler notify callbacks to QCalls (#106604)
Browse files Browse the repository at this point in the history
Remove the no longer needed Thread.InternalGetCurrentThread.
Update generated code to remove passing around Thread*.
Update generated code to get at the Delegate's underlying MethodDesc*. 
No longer emit the "dead" callout code for QCalls - Notificatons to profiler aren't done for QCalls.

 #50306 is being resolved because it was no repro at this point.
  • Loading branch information
AaronRobinsonMSFT authored Aug 20, 2024
1 parent 094649e commit ce3e19f
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 157 deletions.
10 changes: 5 additions & 5 deletions src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,15 +1498,15 @@ internal static void SafeHandleRelease(SafeHandle pHandle)
internal static extern IntPtr GetCOMIPFromRCW(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget, out bool pfNeedsRelease);
#endif // FEATURE_COMINTEROP

#if PROFILING_SUPPORTED
//-------------------------------------------------------
// Profiler helpers
//-------------------------------------------------------
#if PROFILING_SUPPORTED
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr ProfilerBeginTransitionCallback(IntPtr pSecretParam, IntPtr pThread, object pThis);
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_ProfilerBeginTransitionCallback")]
internal static unsafe partial void* ProfilerBeginTransitionCallback(void* pTargetMD);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void ProfilerEndTransitionCallback(IntPtr pMD, IntPtr pThread);
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_ProfilerEndTransitionCallback")]
internal static unsafe partial void ProfilerEndTransitionCallback(void* pTargetMD);
#endif // PROFILING_SUPPORTED

//------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,6 @@ private void StartCallback()
startHelper.Run();
}

// Invoked by VM. Helper method to get a logical thread ID for StringBuilder (for
// correctness) and for FileStream's async code path (for perf, to avoid creating
// a Thread instance).
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern IntPtr InternalGetCurrentThread();

/// <summary>
/// Suspends the current thread for timeout milliseconds. If timeout == 0,
/// forces the thread to give up the remainder of its timeslice. If timeout
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,6 @@ DEFINE_FIELD_U(_startHelper, ThreadBaseObject, m_StartHelper)
DEFINE_FIELD_U(_DONT_USE_InternalThread, ThreadBaseObject, m_InternalThread)
DEFINE_FIELD_U(_priority, ThreadBaseObject, m_Priority)
DEFINE_CLASS(THREAD, Threading, Thread)
DEFINE_METHOD(THREAD, INTERNAL_GET_CURRENT_THREAD, InternalGetCurrentThread, SM_RetIntPtr)
DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, IM_RetVoid)
#ifdef FEATURE_OBJCMARSHAL
DEFINE_CLASS(AUTORELEASEPOOL, Threading, AutoreleasePool)
Expand Down Expand Up @@ -953,8 +952,8 @@ DEFINE_METHOD(STUBHELPERS, SAFE_HANDLE_ADD_REF, SafeHandleAddRef,
DEFINE_METHOD(STUBHELPERS, SAFE_HANDLE_RELEASE, SafeHandleRelease, SM_SafeHandle_RetVoid)

#ifdef PROFILING_SUPPORTED
DEFINE_METHOD(STUBHELPERS, PROFILER_BEGIN_TRANSITION_CALLBACK, ProfilerBeginTransitionCallback, SM_IntPtr_IntPtr_Obj_RetIntPtr)
DEFINE_METHOD(STUBHELPERS, PROFILER_END_TRANSITION_CALLBACK, ProfilerEndTransitionCallback, SM_IntPtr_IntPtr_RetVoid)
DEFINE_METHOD(STUBHELPERS, PROFILER_BEGIN_TRANSITION_CALLBACK, ProfilerBeginTransitionCallback, SM_PtrVoid_RetPtrVoid)
DEFINE_METHOD(STUBHELPERS, PROFILER_END_TRANSITION_CALLBACK, ProfilerEndTransitionCallback, SM_PtrVoid_RetVoid)
#endif

DEFINE_METHOD(STUBHELPERS, MULTICAST_DEBUGGER_TRACE_HELPER, MulticastDebuggerTraceHelper, SM_Obj_Int_RetVoid)
Expand Down
92 changes: 40 additions & 52 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,11 @@ class ILStubState : public StubState
DWORD dwMethodDescLocalNum = (DWORD)-1;

// Notify the profiler of call out of the runtime
if (!SF_IsReverseCOMStub(m_dwStubFlags) && !SF_IsReverseDelegateStub(m_dwStubFlags) && !SF_IsStructMarshalStub(m_dwStubFlags) && CORProfilerTrackTransitions())
if (CORProfilerTrackTransitions()
&& !SF_SkipTransitionNotify(m_dwStubFlags)
&& !SF_IsReverseCOMStub(m_dwStubFlags)
&& !SF_IsReverseDelegateStub(m_dwStubFlags)
&& !SF_IsStructMarshalStub(m_dwStubFlags))
{
dwMethodDescLocalNum = m_slIL.EmitProfilerBeginTransitionCallback(pcsDispatch, m_dwStubFlags);
_ASSERTE(dwMethodDescLocalNum != (DWORD)-1);
Expand Down Expand Up @@ -1103,6 +1107,7 @@ class ILStubState : public StubState
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_CONVSIGASVARARG, " NDIRECTSTUB_FL_CONVSIGASVARARG\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_BESTFIT, " NDIRECTSTUB_FL_BESTFIT\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR, " NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY, " NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_DELEGATE, " NDIRECTSTUB_FL_DELEGATE\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_DOHRESULTSWAPPING, " NDIRECTSTUB_FL_DOHRESULTSWAPPING\n", facility, level);
LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_REVERSE_INTEROP, " NDIRECTSTUB_FL_REVERSE_INTEROP\n", facility, level);
Expand All @@ -1127,6 +1132,7 @@ class ILStubState : public StubState
NDIRECTSTUB_FL_CONVSIGASVARARG |
NDIRECTSTUB_FL_BESTFIT |
NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR |
NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY |
NDIRECTSTUB_FL_DELEGATE |
NDIRECTSTUB_FL_DOHRESULTSWAPPING |
NDIRECTSTUB_FL_REVERSE_INTEROP |
Expand Down Expand Up @@ -1583,7 +1589,6 @@ NDirectStubLinker::NDirectStubLinker(
m_fHasExceptionCleanupCode(FALSE),
m_fCleanupWorkListIsSetup(FALSE),
m_targetHasThis((dwStubFlags & NDIRECTSTUB_FL_TARGET_HAS_THIS) != 0),
m_dwThreadLocalNum(-1),
m_dwCleanupWorkListLocalNum(-1),
m_dwRetValLocalNum(-1),
m_ErrorResID(-1),
Expand Down Expand Up @@ -1815,21 +1820,6 @@ DWORD NDirectStubLinker::GetCleanupWorkListLocalNum()
return m_dwCleanupWorkListLocalNum;
}

DWORD NDirectStubLinker::GetThreadLocalNum()
{
STANDARD_VM_CONTRACT;

if (m_dwThreadLocalNum == (DWORD)-1)
{
// The local is created and initialized lazily when first asked.
m_dwThreadLocalNum = NewLocal(ELEMENT_TYPE_I);
m_pcsSetup->EmitCALL(METHOD__THREAD__INTERNAL_GET_CURRENT_THREAD, 0, 1);
m_pcsSetup->EmitSTLOC(m_dwThreadLocalNum);
}

return m_dwThreadLocalNum;
}

DWORD NDirectStubLinker::GetReturnValueLocalNum()
{
LIMITED_METHOD_CONTRACT;
Expand Down Expand Up @@ -2252,31 +2242,25 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
{
STANDARD_VM_CONTRACT;

if (SF_IsForwardDelegateStub(dwStubFlags) || SF_IsCALLIStub(dwStubFlags))
{
// secret argument does not contain MD nor UMEntryThunk
pcsEmit->EmitLoadNullPtr();
}
else
if (!SF_IsForwardDelegateStub(dwStubFlags) && !SF_IsCALLIStub(dwStubFlags))
{
// COM interop or the pinvoke case, should have a non-null 'secret argument'.
EmitLoadStubContext(pcsEmit, dwStubFlags);
}

pcsEmit->EmitLDLOC(GetThreadLocalNum());

// In the unmanaged delegate case, we need the "this" object to retrieve the MD
// in StubHelpers::ProfilerEnterCallback().
if (SF_IsDelegateStub(dwStubFlags))
else if (SF_IsDelegateStub(dwStubFlags))
{
// In the unmanaged delegate case, we use the "this" object to retrieve the MD
_ASSERTE(SF_IsForwardStub(dwStubFlags));
pcsEmit->EmitLoadThis();
pcsEmit->EmitCALL(METHOD__DELEGATE__GET_INVOKE_METHOD, 1, 1);
}
else
{
pcsEmit->EmitLDNULL();
// It is the calli pinvoke case, so pass null.
pcsEmit->EmitLoadNullPtr();
}

pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_BEGIN_TRANSITION_CALLBACK, 3, 1);
pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_BEGIN_TRANSITION_CALLBACK, 1, 1);

// Store the MD for StubHelpers::ProfilerLeaveCallback().
DWORD dwMethodDescLocalNum = pcsEmit->NewLocal(ELEMENT_TYPE_I);
Expand All @@ -2290,8 +2274,7 @@ void NDirectStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit,

pcsEmit->EmitLDLOC(dwMethodDescLocalNum);
_ASSERTE(SF_IsForwardStub(dwStubFlags));
pcsEmit->EmitLDLOC(GetThreadLocalNum());
pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_END_TRANSITION_CALLBACK, 2, 0);
pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_END_TRANSITION_CALLBACK, 1, 0);
}
#endif // PROFILING_SUPPPORTED

Expand Down Expand Up @@ -4342,6 +4325,11 @@ static void CreateNDirectStubAccessMetadata(
lcidArg = GetLCIDParameterIndex(pMD);
if (lcidArg != -1 && lcidArg > (*pNumArgs))
COMPlusThrow(kIndexOutOfRangeException, IDS_EE_INVALIDLCIDPARAM);

// Do not notify the profiler about QCalls
// See ProfilerManagedToUnmanagedTransitionMD()
if (pMD->IsQCall())
*pdwStubFlags |= NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY;
}

(*piLCIDArg) = lcidArg;
Expand Down Expand Up @@ -5457,30 +5445,30 @@ MethodDesc* NDirect::CreateCLRToNativeILStub(PInvokeStaticSigInfo* pSigInfo,
pSigInfo->GetStubFlags() | dwStubFlags);
}

MethodDesc* NDirect::GetILStubMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags)
namespace
{
CONTRACTL
MethodDesc* GetILStubMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags)
{
STANDARD_VM_CHECK;
PRECONDITION(pNMD != NULL);
}
CONTRACTL_END;
CONTRACTL
{
STANDARD_VM_CHECK;
PRECONDITION(pNMD != NULL);
}
CONTRACTL_END;

MethodDesc* pStubMD = NULL;
MethodDesc* pStubMD = NULL;

if (!pNMD->IsVarArgs() || SF_IsForNumParamBytes(dwStubFlags))
{
pStubMD = CreateCLRToNativeILStub(
pSigInfo,
dwStubFlags & ~NDIRECTSTUB_FL_FOR_NUMPARAMBYTES,
pNMD);
}
if (!pNMD->IsVarArgs() || SF_IsForNumParamBytes(dwStubFlags))
{
pStubMD = NDirect::CreateCLRToNativeILStub(
pSigInfo,
dwStubFlags & ~NDIRECTSTUB_FL_FOR_NUMPARAMBYTES,
pNMD);
}

return pStubMD;
}
return pStubMD;
}

namespace
{
LPVOID NDirectGetEntryPoint(NDirectMethodDesc *pMD, NATIVE_LIBRARY_HANDLE hMod)
{
// GetProcAddress cannot be called while preemptive GC is disabled.
Expand Down Expand Up @@ -5597,7 +5585,7 @@ PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD,
PInvokeStaticSigInfo sigInfo;
NDirect::InitializeSigInfoAndPopulateNDirectMethodDesc(pNMD, &sigInfo);

*ppStubMD = NDirect::GetILStubMethodDesc(pNMD, &sigInfo, dwStubFlags);
*ppStubMD = GetILStubMethodDesc(pNMD, &sigInfo, dwStubFlags);

if (SF_IsForNumParamBytes(dwStubFlags))
return (PCODE)NULL;
Expand Down
6 changes: 2 additions & 4 deletions src/coreclr/vm/dllimport.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ class NDirect
DWORD dwStubFlags,
MethodDesc* pMD);

static MethodDesc* GetILStubMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags);
static PCODE GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, DWORD dwStubFlags);
static PCODE GetStubForILStub(MethodDesc* pMD, MethodDesc** ppStubMD, DWORD dwStubFlags);

Expand All @@ -149,7 +148,7 @@ enum NDirectStubFlags
NDIRECTSTUB_FL_CONVSIGASVARARG = 0x00000001,
NDIRECTSTUB_FL_BESTFIT = 0x00000002,
NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR = 0x00000004,
// unused = 0x00000008,
NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY = 0x00000008,
NDIRECTSTUB_FL_DELEGATE = 0x00000010,
NDIRECTSTUB_FL_DOHRESULTSWAPPING = 0x00000020,
NDIRECTSTUB_FL_REVERSE_INTEROP = 0x00000040,
Expand Down Expand Up @@ -214,6 +213,7 @@ enum ILStubTypes
inline bool SF_IsVarArgStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_CONVSIGASVARARG)); }
inline bool SF_IsBestFit (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_BESTFIT)); }
inline bool SF_IsThrowOnUnmappableChar (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR)); }
inline bool SF_SkipTransitionNotify (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY)); }
inline bool SF_IsDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_DELEGATE)); }
inline bool SF_IsHRESULTSwapping (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_DOHRESULTSWAPPING)); }
inline bool SF_IsReverseStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)); }
Expand Down Expand Up @@ -486,7 +486,6 @@ class NDirectStubLinker : public ILStubLinker
void EmitLoadRCWThis(ILCodeStream *pcsEmit, DWORD dwStubFlags);
#endif // FEATURE_COMINTEROP
DWORD GetCleanupWorkListLocalNum();
DWORD GetThreadLocalNum();
DWORD GetReturnValueLocalNum();
#if defined(TARGET_X86) && defined(FEATURE_IJW)
DWORD GetCopyCtorChainLocalNum();
Expand Down Expand Up @@ -568,7 +567,6 @@ class NDirectStubLinker : public ILStubLinker
BOOL m_fHasExceptionCleanupCode;
BOOL m_fCleanupWorkListIsSetup;
BOOL m_targetHasThis;
DWORD m_dwThreadLocalNum; // managed-to-native only
DWORD m_dwArgMarshalIndexLocalNum;
DWORD m_dwCleanupWorkListLocalNum;
DWORD m_dwRetValLocalNum;
Expand Down
5 changes: 0 additions & 5 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ FCFuncStart(gMathFFuncs)
FCFuncEnd()

FCFuncStart(gThreadFuncs)
FCFuncElement("InternalGetCurrentThread", GetThread)
FCFuncElement("Initialize", ThreadNative::Initialize)
FCFuncElement("GetCurrentThreadNative", ThreadNative::GetCurrentThread)
FCFuncElement("InternalFinalize", ThreadNative::Finalize)
Expand Down Expand Up @@ -453,10 +452,6 @@ FCFuncStart(gStubHelperFuncs)
FCFuncElement("InternalGetCOMHRExceptionObject", StubHelpers::GetCOMHRExceptionObject)
FCFuncElement("GetCOMIPFromRCW", StubHelpers::GetCOMIPFromRCW)
#endif // FEATURE_COMINTEROP
#ifdef PROFILING_SUPPORTED
FCFuncElement("ProfilerBeginTransitionCallback", StubHelpers::ProfilerBeginTransitionCallback)
FCFuncElement("ProfilerEndTransitionCallback", StubHelpers::ProfilerEndTransitionCallback)
#endif
FCFuncElement("AllocateInternal", StubHelpers::AllocateInternal)
FCFuncElement("MarshalToUnmanagedVaListInternal", StubHelpers::MarshalToUnmanagedVaListInternal)
FCFuncElement("MarshalToManagedVaListInternal", StubHelpers::MarshalToManagedVaListInternal)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/metasig.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ DEFINE_METASIG(SM(Int_Int_RetVoid, i i, v))
DEFINE_METASIG(SM(Str_RetIntPtr, s, I))
DEFINE_METASIG(SM(Str_RetBool, s, F))
DEFINE_METASIG(SM(IntPtr_IntPtr_RetVoid, I I, v))
DEFINE_METASIG(SM(IntPtr_IntPtr_Obj_RetIntPtr, I I j, I))
DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Obj_RetIntPtr, I I i j, I))
DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_RetVoid, I I I, v))
DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_UShrt_IntPtr_RetVoid, I I I H I, v))
Expand Down Expand Up @@ -351,6 +350,7 @@ DEFINE_METASIG(SM(PtrChar_RetInt, P(u), i))
DEFINE_METASIG(SM(PtrChar_RetVoid, P(u), v))
DEFINE_METASIG(SM(IntPtr_IntPtr_RetIntPtr, I I, I))
DEFINE_METASIG(SM(IntPtr_IntPtr_Int_RetIntPtr, I I i, I))
DEFINE_METASIG(SM(PtrVoid_RetVoid, P(v), v))
DEFINE_METASIG(SM(PtrVoid_PtrVoid_RetVoid, P(v) P(v), v))
DEFINE_METASIG(SM(PtrVoid_PtrVoid_UInt_RetVoid, P(v) P(v) K, v))
DEFINE_METASIG(IM(Obj_RetBool, j, F))
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ static const Entry s_QCall[] =
DllImportEntry(StubHelpers_CreateCustomMarshalerHelper)
DllImportEntry(StubHelpers_SetStringTrailByte)
DllImportEntry(StubHelpers_ThrowInteropParamException)
#ifdef PROFILING_SUPPORTED
DllImportEntry(StubHelpers_ProfilerBeginTransitionCallback)
DllImportEntry(StubHelpers_ProfilerEndTransitionCallback)
#endif
#if defined(FEATURE_COMINTEROP)
DllImportEntry(ObjectMarshaler_ConvertToNative)
DllImportEntry(ObjectMarshaler_ConvertToManaged)
Expand Down
Loading

0 comments on commit ce3e19f

Please sign in to comment.