Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/8.0-staging] For transition profiler callbacks, always load the thread #105200

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2268,15 +2268,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
EmitLoadStubContext(pcsEmit, dwStubFlags);
}

if (SF_IsForwardStub(dwStubFlags))
{
pcsEmit->EmitLDLOC(GetThreadLocalNum());
}
else
{
// we use a null pThread to indicate reverse interop
pcsEmit->EmitLoadNullPtr();
}
pcsEmit->EmitLDLOC(GetThreadLocalNum());

// In the unmanaged delegate case, we need the "this" object to retrieve the MD
// in StubHelpers::ProfilerEnterCallback().
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/stubhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ FCIMPL3(SIZE_T, StubHelpers::ProfilerBeginTransitionCallback, SIZE_T pSecretPara
}

{
_ASSERTE(pThread != nullptr);
GCX_PREEMP_THREAD_EXISTS(pThread);

ProfilerManagedToUnmanagedTransitionMD(pRealMD, COR_PRF_TRANSITION_CALL);
Expand Down Expand Up @@ -582,6 +583,7 @@ FCIMPL2(void, StubHelpers::ProfilerEndTransitionCallback, MethodDesc* pRealMD, T
// and the transition requires us to set up a HMF.
HELPER_METHOD_FRAME_BEGIN_0();
{
_ASSERTE(pThread != nullptr);
GCX_PREEMP_THREAD_EXISTS(pThread);

ProfilerUnmanagedToManagedTransitionMD(pRealMD, COR_PRF_TRANSITION_RETURN);
Expand Down
1 change: 1 addition & 0 deletions src/tests/profiler/native/profiler.def
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ EXPORTS
DllCanUnloadNow PRIVATE
PassCallbackToProfiler PRIVATE
DoPInvoke PRIVATE
DoPInvokeWithCallbackOnOtherThread PRIVATE

10 changes: 9 additions & 1 deletion src/tests/profiler/native/transitions/transitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ extern "C" EXPORT void STDMETHODCALLTYPE DoPInvoke(int(*callback)(int), int i)
printf("PInvoke received i=%d\n", callback(i));
}

extern "C" EXPORT void STDMETHODCALLTYPE DoPInvokeWithCallbackOnOtherThread(int(*callback)(int), int i)
{
int j = 0;
std::thread t([&j, callback, i] { j = callback(i); });
t.join();
printf("PInvoke with callback on other thread received i=%d\n", j);
}


HRESULT Transitions::UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
{
Expand Down Expand Up @@ -124,4 +132,4 @@ bool Transitions::FunctionIsTargetFunction(FunctionID functionID, TransitionInst
}

return true;
}
}
42 changes: 38 additions & 4 deletions src/tests/profiler/transitions/transitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private static int DoDelegateReversePInvokeNonBlittable(bool b)
public static int BlittablePInvokeToBlittableInteropDelegate()
{
InteropDelegate del = DoDelegateReversePInvoke;

DoPInvoke((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), 13);
GC.KeepAlive(del);

Expand All @@ -42,13 +42,23 @@ public static int BlittablePInvokeToBlittableInteropDelegate()
public static int NonBlittablePInvokeToNonBlittableInteropDelegate()
{
InteropDelegateNonBlittable del = DoDelegateReversePInvokeNonBlittable;

DoPInvokeNonBlitable((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), true);
GC.KeepAlive(del);

return 100;
}

public static int BlittablePInvokeToBlittableInteropDelegateOnOtherThread()
{
InteropDelegate del = DoDelegateReversePInvoke;

DoPInvokeWithCallbackOnOtherThread((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), 13);
GC.KeepAlive(del);

return 100;
}

[UnmanagedCallersOnly]
private static int DoReversePInvoke(int i)
{
Expand All @@ -61,6 +71,9 @@ private static int DoReversePInvoke(int i)
[DllImport("Profiler", EntryPoint = nameof(DoPInvoke))]
public static extern void DoPInvokeNonBlitable(delegate* unmanaged<int,int> callback, bool i);

[DllImport("Profiler")]
public static extern void DoPInvokeWithCallbackOnOtherThread(delegate* unmanaged<int,int> callback, int i);

public static int BlittablePInvokeToUnmanagedCallersOnly()
{
DoPInvoke(&DoReversePInvoke, 13);
Expand All @@ -75,6 +88,13 @@ public static int NonBlittablePInvokeToUnmanagedCallersOnly()
return 100;
}

public static int BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread()
{
DoPInvokeWithCallbackOnOtherThread(&DoReversePInvoke, 13);

return 100;
}

public static int Main(string[] args)
{
if (args.Length > 1 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase))
Expand All @@ -89,6 +109,10 @@ public static int Main(string[] args)
return NonBlittablePInvokeToUnmanagedCallersOnly();
case nameof(NonBlittablePInvokeToNonBlittableInteropDelegate):
return NonBlittablePInvokeToNonBlittableInteropDelegate();
case nameof(BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread):
return BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread();
case nameof(BlittablePInvokeToBlittableInteropDelegateOnOtherThread):
return BlittablePInvokeToBlittableInteropDelegateOnOtherThread();
}
}

Expand All @@ -104,12 +128,22 @@ public static int Main(string[] args)

if (!RunProfilerTest(nameof(NonBlittablePInvokeToUnmanagedCallersOnly), nameof(DoPInvokeNonBlitable), nameof(DoReversePInvoke)))
{
return 101;
return 103;
}

if (!RunProfilerTest(nameof(NonBlittablePInvokeToNonBlittableInteropDelegate), nameof(DoPInvokeNonBlitable), "Invoke"))
{
return 102;
return 104;
}

if (!RunProfilerTest(nameof(BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread), nameof(DoPInvokeWithCallbackOnOtherThread), nameof(DoReversePInvoke)))
{
return 105;
}

if (!RunProfilerTest(nameof(BlittablePInvokeToBlittableInteropDelegateOnOtherThread), nameof(DoPInvokeWithCallbackOnOtherThread), "Invoke"))
{
return 106;
}

return 100;
Expand Down
Loading