summaryrefslogtreecommitdiff
path: root/src/vm/jithelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/jithelpers.cpp')
-rw-r--r--src/vm/jithelpers.cpp319
1 files changed, 16 insertions, 303 deletions
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 32be77823c..8cff03ae60 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -4472,19 +4472,18 @@ HCIMPL_MONHELPER(JIT_MonEnterWorker_Portable, Object* obj)
result = obj->EnterObjMonitorHelper(pCurThread);
if (result == AwareLock::EnterHelperResult_Entered)
{
- MONHELPER_STATE(*pbLockTaken = 1;)
+ MONHELPER_STATE(*pbLockTaken = 1);
return;
}
- else
if (result == AwareLock::EnterHelperResult_Contention)
{
- AwareLock::EnterHelperResult resultSpin = obj->EnterObjMonitorHelperSpin(pCurThread);
- if (resultSpin == AwareLock::EnterHelperResult_Entered)
+ result = obj->EnterObjMonitorHelperSpin(pCurThread);
+ if (result == AwareLock::EnterHelperResult_Entered)
{
- MONHELPER_STATE(*pbLockTaken = 1;)
+ MONHELPER_STATE(*pbLockTaken = 1);
return;
}
- if (resultSpin == AwareLock::EnterHelperResult_Contention)
+ if (result == AwareLock::EnterHelperResult_Contention)
{
FC_INNER_RETURN_VOID(JIT_MonContention_Helper(obj, MONHELPER_ARG, GetEEFuncEntryPointMacro(JIT_MonEnter)));
}
@@ -4519,15 +4518,14 @@ HCIMPL1(void, JIT_MonEnter_Portable, Object* obj)
{
return;
}
- else
if (result == AwareLock::EnterHelperResult_Contention)
{
- AwareLock::EnterHelperResult resultSpin = obj->EnterObjMonitorHelperSpin(pCurThread);
- if (resultSpin == AwareLock::EnterHelperResult_Entered)
+ result = obj->EnterObjMonitorHelperSpin(pCurThread);
+ if (result == AwareLock::EnterHelperResult_Entered)
{
return;
}
- if (resultSpin == AwareLock::EnterHelperResult_Contention)
+ if (result == AwareLock::EnterHelperResult_Contention)
{
FC_INNER_RETURN_VOID(JIT_MonContention_Helper(obj, NULL, GetEEFuncEntryPointMacro(JIT_MonEnter)));
}
@@ -4563,16 +4561,15 @@ HCIMPL2(void, JIT_MonReliableEnter_Portable, Object* obj, BYTE* pbLockTaken)
*pbLockTaken = 1;
return;
}
- else
if (result == AwareLock::EnterHelperResult_Contention)
{
- AwareLock::EnterHelperResult resultSpin = obj->EnterObjMonitorHelperSpin(pCurThread);
- if (resultSpin == AwareLock::EnterHelperResult_Entered)
+ result = obj->EnterObjMonitorHelperSpin(pCurThread);
+ if (result == AwareLock::EnterHelperResult_Entered)
{
*pbLockTaken = 1;
return;
}
- if (resultSpin == AwareLock::EnterHelperResult_Contention)
+ if (result == AwareLock::EnterHelperResult_Contention)
{
FC_INNER_RETURN_VOID(JIT_MonContention_Helper(obj, pbLockTaken, GetEEFuncEntryPointMacro(JIT_MonReliableEnter)));
}
@@ -4649,14 +4646,15 @@ HCIMPL3(void, JIT_MonTryEnter_Portable, Object* obj, INT32 timeOut, BYTE* pbLock
*pbLockTaken = 1;
return;
}
- else
if (result == AwareLock::EnterHelperResult_Contention)
{
if (timeOut == 0)
+ {
return;
+ }
- AwareLock::EnterHelperResult resultSpin = obj->EnterObjMonitorHelperSpin(pCurThread);
- if (resultSpin == AwareLock::EnterHelperResult_Entered)
+ result = obj->EnterObjMonitorHelperSpin(pCurThread);
+ if (result == AwareLock::EnterHelperResult_Entered)
{
*pbLockTaken = 1;
return;
@@ -4741,7 +4739,6 @@ FCIMPL1(void, JIT_MonExit_Portable, Object* obj)
{
return;
}
- else
if (action == AwareLock::LeaveHelperAction_Signal)
{
FC_INNER_RETURN_VOID(JIT_MonExit_Signal(obj));
@@ -4773,7 +4770,6 @@ HCIMPL_MONHELPER(JIT_MonExitWorker_Portable, Object* obj)
MONHELPER_STATE(*pbLockTaken = 0;)
return;
}
- else
if (action == AwareLock::LeaveHelperAction_Signal)
{
MONHELPER_STATE(*pbLockTaken = 0;)
@@ -4821,7 +4817,7 @@ HCIMPL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock)
goto FramedLockHelper;
}
- if (lock->EnterHelper(pCurThread) == AwareLock::EnterHelperResult_Entered)
+ if (lock->EnterHelper(pCurThread, true /* checkRecursiveCase */))
{
#if defined(_DEBUG) && defined(TRACK_SYNC)
// The best place to grab this is from the ECall frame
@@ -4909,289 +4905,6 @@ HCIMPL_MONHELPER(JIT_MonExitStatic_Portable, AwareLock *lock)
HCIMPLEND
#include <optdefault.h>
-/*********************************************************************/
-// JITutil_Mon* are helpers than handle slow paths for JIT_Mon* methods
-// implemented in assembly. They are not doing any spinning compared
-// to the full fledged portable implementations above.
-/*********************************************************************/
-
-/*********************************************************************/
-HCIMPL_MONHELPER(JITutil_MonEnterWorker, Object* obj)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- OBJECTREF objRef = ObjectToOBJECTREF(obj);
-
- // The following makes sure that Monitor.Enter shows up on thread abort
- // stack walks (otherwise Monitor.Enter called within a CER can block a
- // thread abort indefinitely). Setting the __me internal variable (normally
- // only set for fcalls) will cause the helper frame below to be able to
- // backtranslate into the method desc for the Monitor.Enter fcall.
- //
- // Note that we need explicitly initialize Monitor.Enter fcall in
- // code:SystemDomain::LoadBaseSystemClasses to make this work in the case
- // where the first call ever to Monitor.Enter is done as JIT helper
- // for synchronized method.
- __me = GetEEFuncEntryPointMacro(JIT_MonEnter);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH, objRef);
-
- if (objRef == NULL)
- COMPlusThrow(kArgumentNullException);
-
- MONHELPER_STATE(GCPROTECT_BEGININTERIOR(pbLockTaken);)
-
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- DWORD lockCount = pThread->m_dwLockCount;
-#endif
- if (GET_THREAD()->CatchAtSafePointOpportunistic())
- {
- GET_THREAD()->PulseGCMode();
- }
- objRef->EnterObjMonitor();
- _ASSERTE ((objRef->GetSyncBlock()->GetMonitor()->m_Recursion == 1 && pThread->m_dwLockCount == lockCount + 1) ||
- pThread->m_dwLockCount == lockCount);
- MONHELPER_STATE(if (pbLockTaken != 0) *pbLockTaken = 1;)
-
- MONHELPER_STATE(GCPROTECT_END();)
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-/*********************************************************************/
-
-// This helper is only ever used as part of FCall, but it is implemented using HCIMPL macro
-// so that it can be tail called from assembly helper without triggering asserts in debug.
-HCIMPL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- OBJECTREF objRef = ObjectToOBJECTREF(obj);
-
- // The following makes sure that Monitor.Enter shows up on thread abort
- // stack walks (otherwise Monitor.Enter called within a CER can block a
- // thread abort indefinitely). Setting the __me internal variable (normally
- // only set for fcalls) will cause the helper frame below to be able to
- // backtranslate into the method desc for the Monitor.Enter fcall.
- __me = GetEEFuncEntryPointMacro(JIT_MonReliableEnter);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH, objRef);
-
- if (objRef == NULL)
- COMPlusThrow(kArgumentNullException);
-
- GCPROTECT_BEGININTERIOR(pbLockTaken);
-
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- DWORD lockCount = pThread->m_dwLockCount;
-#endif
- if (GET_THREAD()->CatchAtSafePointOpportunistic())
- {
- GET_THREAD()->PulseGCMode();
- }
- objRef->EnterObjMonitor();
- _ASSERTE ((objRef->GetSyncBlock()->GetMonitor()->m_Recursion == 1 && pThread->m_dwLockCount == lockCount + 1) ||
- pThread->m_dwLockCount == lockCount);
- *pbLockTaken = 1;
-
- GCPROTECT_END();
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-
-/*********************************************************************/
-
-// This helper is only ever used as part of FCall, but it is implemented using HCIMPL macro
-// so that it can be tail called from assembly helper without triggering asserts in debug.
-HCIMPL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- BOOL result = FALSE;
-
- OBJECTREF objRef = ObjectToOBJECTREF(obj);
-
- // The following makes sure that Monitor.TryEnter shows up on thread
- // abort stack walks (otherwise Monitor.TryEnter called within a CER can
- // block a thread abort for long periods of time). Setting the __me internal
- // variable (normally only set for fcalls) will cause the helper frame below
- // to be able to backtranslate into the method desc for the Monitor.TryEnter
- // fcall.
- __me = GetEEFuncEntryPointMacro(JIT_MonTryEnter);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH, objRef);
-
- if (objRef == NULL)
- COMPlusThrow(kArgumentNullException);
-
- if (timeOut < -1)
- COMPlusThrow(kArgumentOutOfRangeException);
-
- GCPROTECT_BEGININTERIOR(pbLockTaken);
-
- if (GET_THREAD()->CatchAtSafePointOpportunistic())
- {
- GET_THREAD()->PulseGCMode();
- }
-
- result = objRef->TryEnterObjMonitor(timeOut);
- *pbLockTaken = result != FALSE;
-
- GCPROTECT_END();
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-/*********************************************************************/
-HCIMPL_MONHELPER(JITutil_MonExitWorker, Object* obj)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- MONHELPER_STATE(if (pbLockTaken != NULL && *pbLockTaken == 0) return;)
-
- OBJECTREF objRef = ObjectToOBJECTREF(obj);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT|Frame::FRAME_ATTR_EXACT_DEPTH, objRef);
-
- if (objRef == NULL)
- COMPlusThrow(kArgumentNullException);
-
- if (!objRef->LeaveObjMonitor())
- COMPlusThrow(kSynchronizationLockException);
-
- MONHELPER_STATE(if (pbLockTaken != 0) *pbLockTaken = 0;)
-
- TESTHOOKCALL(AppDomainCanBeUnloaded(GET_THREAD()->GetDomain()->GetId().m_dwId,FALSE));
-
- if (GET_THREAD()->IsAbortRequested()) {
- GET_THREAD()->HandleThreadAbort();
- }
-
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-/*********************************************************************/
-// A helper for JIT_MonEnter that is on the callee side of an ecall
-// frame and handles the contention case.
-
-HCIMPL_MONHELPER(JITutil_MonContention, AwareLock* lock)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- // The following makes sure that Monitor.Enter shows up on thread abort
- // stack walks (otherwise Monitor.Enter called within a CER can block a
- // thread abort indefinitely). Setting the __me internal variable (normally
- // only set for fcalls) will cause the helper frame below to be able to
- // backtranslate into the method desc for the Monitor.Enter fcall.
- __me = GetEEFuncEntryPointMacro(JIT_MonEnter);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB(Frame::FRAME_ATTR_EXACT_DEPTH);
- MONHELPER_STATE(GCPROTECT_BEGININTERIOR(pbLockTaken);)
-
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- DWORD lockCount = pThread->m_dwLockCount;
-#endif
- lock->Contention();
- _ASSERTE (pThread->m_dwLockCount == lockCount + 1);
- MONHELPER_STATE(if (pbLockTaken != 0) *pbLockTaken = 1;)
-
- MONHELPER_STATE(GCPROTECT_END();)
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-// This helper is only ever used as part of FCall, but it is implemented using HCIMPL macro
-// so that it can be tail called from assembly helper without triggering asserts in debug.
-HCIMPL2(void, JITutil_MonReliableContention, AwareLock* lock, BYTE* pbLockTaken)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- // The following makes sure that Monitor.Enter shows up on thread abort
- // stack walks (otherwise Monitor.Enter called within a CER can block a
- // thread abort indefinitely). Setting the __me internal variable (normally
- // only set for fcalls) will cause the helper frame below to be able to
- // backtranslate into the method desc for the Monitor.Enter fcall.
- __me = GetEEFuncEntryPointMacro(JIT_MonReliableEnter);
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB(Frame::FRAME_ATTR_EXACT_DEPTH);
- GCPROTECT_BEGININTERIOR(pbLockTaken);
-
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- DWORD lockCount = pThread->m_dwLockCount;
-#endif
- lock->Contention();
- _ASSERTE (pThread->m_dwLockCount == lockCount + 1);
- *pbLockTaken = 1;
-
- GCPROTECT_END();
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-/*********************************************************************/
-// A helper for JIT_MonExit and JIT_MonExitStatic that is on the
-// callee side of an ecall frame and handles cases that might allocate,
-// throw or block.
-HCIMPL_MONHELPER(JITutil_MonSignal, AwareLock* lock)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- // Monitor helpers are used as both hcalls and fcalls, thus we need exact depth.
- HELPER_METHOD_FRAME_BEGIN_ATTRIB(Frame::FRAME_ATTR_EXACT_DEPTH | Frame::FRAME_ATTR_NO_THREAD_ABORT);
-
- lock->Signal();
- MONHELPER_STATE(if (pbLockTaken != 0) *pbLockTaken = 0;)
-
- TESTHOOKCALL(AppDomainCanBeUnloaded(GET_THREAD()->GetDomain()->GetId().m_dwId,FALSE));
-
- if (GET_THREAD()->IsAbortRequested()) {
- GET_THREAD()->HandleThreadAbort();
- }
-
- HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
HCIMPL1(void *, JIT_GetSyncFromClassHandle, CORINFO_CLASS_HANDLE typeHnd_)
CONTRACTL {
FCALL_CHECK;