diff options
Diffstat (limited to 'src/Native/Runtime/thread.cpp')
-rw-r--r-- | src/Native/Runtime/thread.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/src/Native/Runtime/thread.cpp b/src/Native/Runtime/thread.cpp index 994c21dad..aaefff971 100644 --- a/src/Native/Runtime/thread.cpp +++ b/src/Native/Runtime/thread.cpp @@ -31,7 +31,8 @@ #ifndef DACCESS_COMPILE EXTERN_C REDHAWK_API void* REDHAWK_CALLCONV RhpHandleAlloc(void* pObject, int type); -EXTERN_C REDHAWK_API void REDHAWK_CALLCONV RhHandleFree(void*); +EXTERN_C REDHAWK_API void REDHAWK_CALLCONV RhHandleSet(void* handle, void* pObject); +EXTERN_C REDHAWK_API void REDHAWK_CALLCONV RhHandleFree(void* handle); static int (*g_RuntimeInitializationCallback)(); static Thread* g_RuntimeInitializingThread; @@ -132,7 +133,7 @@ void Thread::ResetCachedTransitionFrame() // This function simulates a PInvoke transition using a frame pointer from somewhere further up the stack that // was passed in via the m_pHackPInvokeTunnel field. It is used to allow us to grandfather-in the set of GC // code that runs in cooperative mode without having to rewrite it in managed code. The result is that the -// code that calls into this special mode must spill preserved registeres as if it's going to PInvoke, but +// code that calls into this special mode must spill preserved registers as if it's going to PInvoke, but // record its transition frame pointer in m_pHackPInvokeTunnel and leave the thread in the cooperative // mode. Later on, when this function is called, we effect the state transition to 'unmanaged' using the // previously setup transition frame. @@ -727,8 +728,6 @@ bool Thread::InternalHijack(PAL_LIMITED_CONTEXT * pSuspendCtx, void * pvHijackTa if (frameIterator.IsValid()) { - CrossThreadUnhijack(); - frameIterator.CalculateCurrentMethodState(); frameIterator.GetCodeManager()->UnsynchronizedHijackMethodLoops(frameIterator.GetMethodInfo()); @@ -737,10 +736,16 @@ bool Thread::InternalHijack(PAL_LIMITED_CONTEXT * pSuspendCtx, void * pvHijackTa GCRefKind retValueKind; if (frameIterator.GetCodeManager()->GetReturnAddressHijackInfo(frameIterator.GetMethodInfo(), - frameIterator.GetRegisterSet(), - &ppvRetAddrLocation, - &retValueKind)) + frameIterator.GetRegisterSet(), + &ppvRetAddrLocation, + &retValueKind)) { + // ARM64 epilogs have a window between loading the hijackable return address into LR and the RET instruction. + // We cannot hijack or unhijack a thread while it is suspended in that window unless we implement hijacking + // via LR register modification. Therefore it is important to check our ability to hijack the thread before + // unhijacking it. + CrossThreadUnhijack(); + void* pvRetAddr = *ppvRetAddrLocation; ASSERT(ppvRetAddrLocation != NULL); ASSERT(pvRetAddr != NULL); @@ -1318,26 +1323,27 @@ Boolean Thread::SetThreadStaticStorageForModule(Object * pStorage, UInt32 module m_numThreadLocalModuleStatics = newSize; } - void* threadStaticsStorageHandle = RhpHandleAlloc(pStorage, 2 /* Normal */); - if (threadStaticsStorageHandle == NULL) + if (m_pThreadLocalModuleStatics[moduleIndex] != NULL) { - return FALSE; + RhHandleSet(m_pThreadLocalModuleStatics[moduleIndex], pStorage); } - - // Free the existing storage before assigning a new one - if (m_pThreadLocalModuleStatics[moduleIndex] != NULL) + else { - RhHandleFree(m_pThreadLocalModuleStatics[moduleIndex]); + void* threadStaticsStorageHandle = RhpHandleAlloc(pStorage, 2 /* Normal */); + if (threadStaticsStorageHandle == NULL) + { + return FALSE; + } + m_pThreadLocalModuleStatics[moduleIndex] = threadStaticsStorageHandle; } - m_pThreadLocalModuleStatics[moduleIndex] = threadStaticsStorageHandle; return TRUE; } -COOP_PINVOKE_HELPER(Array*, RhGetThreadStaticStorageForModule, (UInt32 moduleIndex)) +COOP_PINVOKE_HELPER(Object*, RhGetThreadStaticStorageForModule, (UInt32 moduleIndex)) { Thread * pCurrentThread = ThreadStore::RawGetCurrentThread(); - return (Array*)pCurrentThread->GetThreadStaticStorageForModule(moduleIndex); + return pCurrentThread->GetThreadStaticStorageForModule(moduleIndex); } COOP_PINVOKE_HELPER(Boolean, RhSetThreadStaticStorageForModule, (Array * pStorage, UInt32 moduleIndex)) @@ -1357,6 +1363,12 @@ COOP_PINVOKE_HELPER(UInt8*, RhCurrentNativeThreadId, ()) } #endif // !PROJECTN +// This function is used to get the OS thread identifier for the current thread. +COOP_PINVOKE_HELPER(UInt64, RhCurrentOSThreadId, ()) +{ + return PalGetCurrentThreadIdForLogging(); +} + // Standard calling convention variant and actual implementation for RhpReversePInvokeAttachOrTrapThread EXTERN_C NOINLINE void FASTCALL RhpReversePInvokeAttachOrTrapThread2(ReversePInvokeFrame * pFrame) { |