Skip to content

Commit

Permalink
Swap to OS thread for special cases
Browse files Browse the repository at this point in the history
- where we don't use an FCall or standard P/Invoke transition to go to C++ code
- Do so by generalizing the C++ lambda technique used for the FCall transitions and make it available as a macro for these other transitions to use

Fixes dotnet#2051
  • Loading branch information
davidwrighton committed Oct 28, 2022
1 parent 8f6561a commit d6b6414
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 22 deletions.
7 changes: 6 additions & 1 deletion src/coreclr/vm/callcounting.cpp
Expand Up @@ -743,8 +743,13 @@ bool CallCountingManager::SetCodeEntryPoint(

extern "C" PCODE STDCALL OnCallCountThresholdReached(TransitionBlock *transitionBlock, TADDR stubIdentifyingToken)
{
PCODE result = NULL;
WRAPPER_NO_CONTRACT;
return CallCountingManager::OnCallCountThresholdReached(transitionBlock, stubIdentifyingToken);
ENSURE_ON_OS_THREAD();
result = CallCountingManager::OnCallCountThresholdReached(transitionBlock, stubIdentifyingToken);
END_ENSURE_ON_OS_THREAD();

return result;
}

PCODE CallCountingManager::OnCallCountThresholdReached(TransitionBlock *transitionBlock, TADDR stubIdentifyingToken)
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/vm/clrtocomcall.cpp
Expand Up @@ -686,6 +686,9 @@ UINT32 CLRToCOMLateBoundWorker(
/*static*/
UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMethodDesc * pMD)
{
UINT32 returnValue = 0;

ENSURE_ON_OS_THREAD();
CONTRACTL
{
THROWS;
Expand All @@ -696,7 +699,6 @@ UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMet
}
CONTRACTL_END;

UINT32 returnValue = 0;

// This must happen before the UnC handler is setup. Otherwise, an exception will
// cause the UnC handler to pop this frame, leaving a GC hole a mile wide.
Expand Down Expand Up @@ -748,6 +750,7 @@ UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMet

pFrame->Pop(CURRENT_THREAD);

END_ENSURE_ON_OS_THREAD();
return returnValue;
}

Expand Down
11 changes: 7 additions & 4 deletions src/coreclr/vm/comcallablewrapper.cpp
Expand Up @@ -395,7 +395,10 @@ bool IsOleAutDispImplRequiredForClass(MethodTable *pClass)
//--------------------------------------------------------------------------
extern "C" PCODE ComPreStubWorker(ComPrestubMethodFrame *pPFrame, UINT64 *pErrorReturn)
{
CONTRACT (PCODE)
PCODE retAddr = NULL;
ENSURE_ON_OS_THREAD();

CONTRACT_VOID
{
NOTHROW;
GC_TRIGGERS;
Expand All @@ -407,7 +410,6 @@ extern "C" PCODE ComPreStubWorker(ComPrestubMethodFrame *pPFrame, UINT64 *pError
CONTRACT_END;

HRESULT hr = S_OK;
PCODE retAddr = NULL;

BEGIN_ENTRYPOINT_VOIDRET;

Expand Down Expand Up @@ -602,8 +604,9 @@ extern "C" PCODE ComPreStubWorker(ComPrestubMethodFrame *pPFrame, UINT64 *pError
Exit:

END_ENTRYPOINT_VOIDRET;

RETURN retAddr;
RETURN;
END_ENSURE_ON_OS_THREAD();
return retAddr;
}

FORCEINLINE void CPListRelease(CQuickArray<ConnectionPoint*>* value)
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/dllimport.cpp
Expand Up @@ -5823,6 +5823,7 @@ void MarshalStructViaILStubCode(PCODE pStubCode, void* pManagedData, void* pNati
EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)
{
LPVOID ret = NULL;
ENSURE_ON_OS_THREAD();

BEGIN_PRESERVE_LAST_ERROR;

Expand Down Expand Up @@ -5876,6 +5877,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;

END_PRESERVE_LAST_ERROR;
END_ENSURE_ON_OS_THREAD();

return ret;
}
Expand All @@ -5887,6 +5889,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)

EXTERN_C void STDCALL VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock, VASigCookie *pVASigCookie, MethodDesc *pMD)
{
ENSURE_ON_OS_THREAD();
BEGIN_PRESERVE_LAST_ERROR;

STATIC_CONTRACT_THROWS;
Expand All @@ -5913,10 +5916,12 @@ EXTERN_C void STDCALL VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock
pFrame->Pop(CURRENT_THREAD);

END_PRESERVE_LAST_ERROR;
END_ENSURE_ON_OS_THREAD();
}

EXTERN_C void STDCALL GenericPInvokeCalliStubWorker(TransitionBlock * pTransitionBlock, VASigCookie * pVASigCookie, PCODE pUnmanagedTarget)
{
ENSURE_ON_OS_THREAD();
BEGIN_PRESERVE_LAST_ERROR;

STATIC_CONTRACT_THROWS;
Expand All @@ -5942,6 +5947,7 @@ EXTERN_C void STDCALL GenericPInvokeCalliStubWorker(TransitionBlock * pTransitio
pFrame->Pop(CURRENT_THREAD);

END_PRESERVE_LAST_ERROR;
END_ENSURE_ON_OS_THREAD();
}

PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD)
Expand Down
27 changes: 15 additions & 12 deletions src/coreclr/vm/fcall.h
Expand Up @@ -554,6 +554,17 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
#define FORLAZYMACHSTATE_DEBUG_OK_TO_RETURN_END DEBUG_OK_TO_RETURN_END(LAZYMACHSTATE)
#endif

#define ENSURE_ON_OS_THREAD() \
auto osThreadLambda = [&]() -> void { \
do { ; } while(0)

#define END_ENSURE_ON_OS_THREAD() \
}; \
auto nonCapturingLambda = [](uintptr_t pointerToLambda) { \
(*(decltype(osThreadLambda)*)pointerToLambda)(); \
}; \
CallOnOSThread(nonCapturingLambda, (uintptr_t)&osThreadLambda)

// BEGIN: before gcpoll
//FCallGCCanTriggerNoDtor __fcallGcCanTrigger;
//__fcallGcCanTrigger.Enter();
Expand Down Expand Up @@ -587,13 +598,13 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
__helperframe.Push(); \
MAKE_CURRENT_THREAD_AVAILABLE_EX(__helperframe.GetThread()); \
INSTALL_UNWIND_AND_CONTINUE_HANDLER_FOR_HMF(&__helperframe); \
auto helperFrameLambda = [&](){
ENSURE_ON_OS_THREAD();

#define HELPER_METHOD_FRAME_BEGIN_EX_NOTHROW(ret, helperFrame, gcpoll, allowGC, probeFailExpr) \
HELPER_METHOD_FRAME_BEGIN_EX_BODY(ret, helperFrame, gcpoll, allowGC) \
__helperframe.Push(); \
MAKE_CURRENT_THREAD_AVAILABLE_EX(__helperframe.GetThread()); \
auto helperFrameLambda = [&](){ \
ENSURE_ON_OS_THREAD(); \
/* <TODO>TODO TURN THIS ON!!! </TODO> */ \
/* gcpoll; */

Expand All @@ -618,22 +629,14 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
} FORLAZYMACHSTATE_ENDLOOP(alwaysZero);

#define HELPER_METHOD_FRAME_END_EX(gcpoll,allowGC) \
}; \
auto nonCapturingLambda = [](uintptr_t pointerToLambda) { \
(*(decltype(helperFrameLambda)*)pointerToLambda)(); \
}; \
CallOnOSThread(nonCapturingLambda, (uintptr_t)&helperFrameLambda); \
END_ENSURE_ON_OS_THREAD(); \
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; \
__helperframe.Pop(); \
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; \
HELPER_METHOD_FRAME_END_EX_BODY(gcpoll,allowGC);

#define HELPER_METHOD_FRAME_END_EX_NOTHROW(gcpoll,allowGC) \
}; \
auto nonCapturingLambda = [](uintptr_t pointerToLambda) { \
(*(decltype(helperFrameLambda)*)pointerToLambda)(); \
}; \
CallOnOSThread(nonCapturingLambda, (uintptr_t)&helperFrameLambda); \
END_ENSURE_ON_OS_THREAD(); \
__helperframe.Pop(); \
HELPER_METHOD_FRAME_END_EX_BODY(gcpoll,allowGC);

Expand Down
8 changes: 7 additions & 1 deletion src/coreclr/vm/prestub.cpp
Expand Up @@ -1855,6 +1855,7 @@ static PCODE PreStubWorker_Preemptive(
extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, MethodDesc* pMD)
{
PCODE pbRetVal = NULL;
ENSURE_ON_OS_THREAD();

BEGIN_PRESERVE_LAST_ERROR;

Expand Down Expand Up @@ -1955,6 +1956,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method

END_PRESERVE_LAST_ERROR;

END_ENSURE_ON_OS_THREAD();
return pbRetVal;
}

Expand Down Expand Up @@ -2364,6 +2366,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl
//

PCODE pCode = NULL;
ENSURE_ON_OS_THREAD();

BEGIN_PRESERVE_LAST_ERROR;

Expand Down Expand Up @@ -2647,7 +2650,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl
pEMFrame->Pop(CURRENT_THREAD); // Pop the ExternalMethodFrame from the frame stack

END_PRESERVE_LAST_ERROR;

END_ENSURE_ON_OS_THREAD();
return pCode;
}

Expand Down Expand Up @@ -3296,6 +3299,7 @@ PCODE DynamicHelperFixup(TransitionBlock * pTransitionBlock, TADDR * pCell, DWOR
extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock, TADDR * pCell, DWORD sectionIndex, Module * pModule, INT frameFlags)
{
PCODE pHelper = NULL;
ENSURE_ON_OS_THREAD();
SIZE_T result = NULL;

STATIC_CONTRACT_THROWS;
Expand Down Expand Up @@ -3419,6 +3423,8 @@ extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock

if (pHelper == NULL)
*(SIZE_T *)((TADDR)pTransitionBlock + TransitionBlock::GetOffsetOfArgumentRegisters()) = result;

END_ENSURE_ON_OS_THREAD();
return pHelper;
}

Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/vm/virtualcallstub.cpp
Expand Up @@ -1412,6 +1412,8 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
#endif
)
{
PCODE target = NULL;
ENSURE_ON_OS_THREAD();
CONTRACTL {
THROWS;
GC_TRIGGERS;
Expand All @@ -1437,8 +1439,6 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
_ASSERTE(protectedObj != NULL);
OBJECTREF pObj = *protectedObj;

PCODE target = NULL;

if (pObj == NULL) {
pSDFrame->SetForNullReferenceException();
pSDFrame->Push(CURRENT_THREAD);
Expand All @@ -1465,7 +1465,7 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
pMgr->BackPatchWorker(&callSite);
}

return target;
return;
}
#endif

Expand Down Expand Up @@ -1521,6 +1521,7 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
pSDFrame->Pop(CURRENT_THREAD);
END_ENSURE_ON_OS_THREAD();

return target;
}
Expand Down

0 comments on commit d6b6414

Please sign in to comment.