Remove GETTHREAD_ALLOWED tracking (#50080)
authorVladimir Sadov <vsadov@microsoft.com>
Thu, 25 Mar 2021 21:26:44 +0000 (14:26 -0700)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 21:26:44 +0000 (21:26 +0000)
* Remove GETTHREAD_ALLOWED tracking

* removed EE_THREAD_NOT_REQUIRED

* removed EE_THREAD_REQUIRED

* step1

* more changes

* fix Unix build

* more changes

* GetThread in pinvokestubs.S

* build fix for dac

* PInvokeGetThreadHelper

* more changes (dac)

* more (cordbe)

* more (nearly all?)

* Couple places that were mistakengly set to use `GetThreaNotOk` (should use `GetThreadNULLOk`)

* Renamed GetThread() -> GetThreadDoNotUse()

* Missed a few uses of GetThread()

* One more case of GetThread

* Bring GetThread() back - now with an assert in it.

* Renamed PInvokeGetThreadHelper -> JitGetThreadHelper

* One place that should use GetThreadNULLOk (otherwise there are asserts)

* Apply suggestions from code review

Jan's 74 suggestions.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* remove SetFiberMode - it is dead code

* Make `EE_THREAD_NOT_REQUIRED` a noop and revert its removal.

* `GetThreadNULLOk()` should be used here.

* PR review suggestion

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* renamed JitGetThreadHelper -> GetThreadHelper

* One more place that should use `GetThreadNULLOk()`.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
105 files changed:
src/coreclr/debug/daccess/reimpl.cpp
src/coreclr/debug/ee/canary.cpp
src/coreclr/debug/ee/controller.cpp
src/coreclr/debug/ee/debugger.cpp
src/coreclr/debug/ee/debugger.h
src/coreclr/debug/ee/frameinfo.cpp
src/coreclr/inc/contract.h
src/coreclr/inc/ex.h
src/coreclr/vm/amd64/excepamd64.cpp
src/coreclr/vm/amd64/jitinterfaceamd64.cpp
src/coreclr/vm/amd64/pinvokestubs.S
src/coreclr/vm/appdomain.cpp
src/coreclr/vm/appdomain.hpp
src/coreclr/vm/arm/exceparm.cpp
src/coreclr/vm/arm/pinvokestubs.S
src/coreclr/vm/arm/stubs.cpp
src/coreclr/vm/arm64/pinvokestubs.S
src/coreclr/vm/arm64/stubs.cpp
src/coreclr/vm/assembly.cpp
src/coreclr/vm/binder.cpp
src/coreclr/vm/callcounting.cpp
src/coreclr/vm/callhelpers.cpp
src/coreclr/vm/ceemain.cpp
src/coreclr/vm/classcompat.cpp
src/coreclr/vm/clrex.cpp
src/coreclr/vm/clrex.h
src/coreclr/vm/clrtocomcall.cpp
src/coreclr/vm/clsload.cpp
src/coreclr/vm/codeman.cpp
src/coreclr/vm/comcache.cpp
src/coreclr/vm/cominterfacemarshaler.cpp
src/coreclr/vm/common.h
src/coreclr/vm/compile.cpp
src/coreclr/vm/comthreadpool.cpp
src/coreclr/vm/comtoclrcall.cpp
src/coreclr/vm/comutilnative.cpp
src/coreclr/vm/contractimpl.cpp
src/coreclr/vm/corhost.cpp
src/coreclr/vm/crst.cpp
src/coreclr/vm/dbginterface.h
src/coreclr/vm/debugdebugger.cpp
src/coreclr/vm/debughelp.cpp
src/coreclr/vm/dllimportcallback.cpp
src/coreclr/vm/domainfile.cpp
src/coreclr/vm/dwreport.cpp
src/coreclr/vm/eecontract.cpp
src/coreclr/vm/eecontract.h
src/coreclr/vm/eedbginterfaceimpl.cpp
src/coreclr/vm/eehash.inl
src/coreclr/vm/eepolicy.cpp
src/coreclr/vm/eetoprofinterfaceimpl.cpp
src/coreclr/vm/encee.cpp
src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h
src/coreclr/vm/eventpipeinternal.cpp
src/coreclr/vm/eventreporter.cpp
src/coreclr/vm/eventtrace.cpp
src/coreclr/vm/excep.cpp
src/coreclr/vm/exceptionhandling.cpp
src/coreclr/vm/exinfo.cpp
src/coreclr/vm/exstate.cpp
src/coreclr/vm/fcall.cpp
src/coreclr/vm/finalizerthread.cpp
src/coreclr/vm/finalizerthread.h
src/coreclr/vm/frames.cpp
src/coreclr/vm/gccover.cpp
src/coreclr/vm/gcenv.ee.cpp
src/coreclr/vm/gcstress.h
src/coreclr/vm/hash.cpp
src/coreclr/vm/hosting.cpp
src/coreclr/vm/i386/excepx86.cpp
src/coreclr/vm/i386/jitinterfacex86.cpp
src/coreclr/vm/i386/stublinkerx86.cpp
src/coreclr/vm/ibclogger.cpp
src/coreclr/vm/interoputil.cpp
src/coreclr/vm/interpreter.cpp
src/coreclr/vm/jithelpers.cpp
src/coreclr/vm/jithost.cpp
src/coreclr/vm/jitinterface.cpp
src/coreclr/vm/jitinterface.h
src/coreclr/vm/methodtable.cpp
src/coreclr/vm/methodtablebuilder.cpp
src/coreclr/vm/nativeoverlapped.cpp
src/coreclr/vm/object.cpp
src/coreclr/vm/prestub.cpp
src/coreclr/vm/profilinghelper.inl
src/coreclr/vm/proftoeeinterfaceimpl.cpp
src/coreclr/vm/proftoeeinterfaceimpl.inl
src/coreclr/vm/runtimecallablewrapper.cpp
src/coreclr/vm/simplerwlock.cpp
src/coreclr/vm/spinlock.cpp
src/coreclr/vm/stackwalk.cpp
src/coreclr/vm/stringliteralmap.h
src/coreclr/vm/syncblk.cpp
src/coreclr/vm/syncclean.cpp
src/coreclr/vm/synch.cpp
src/coreclr/vm/threadpoolrequest.cpp
src/coreclr/vm/threads.cpp
src/coreclr/vm/threads.h
src/coreclr/vm/threads.inl
src/coreclr/vm/threadstatics.h
src/coreclr/vm/threadsuspend.cpp
src/coreclr/vm/util.cpp
src/coreclr/vm/virtualcallstub.cpp
src/coreclr/vm/win32threadpool.cpp
src/coreclr/vm/win32threadpool.h

index 63beae0..0c94f50 100644 (file)
@@ -63,7 +63,7 @@ DacGetThread(ULONG32 osThread)
     return NULL;
 }
 
-EXTERN_C Thread* GetThread()
+Thread* GetThread()
 {
     // In dac mode it's unlikely that the thread calling dac
     // is actually the same "current thread" that the runtime cares
@@ -75,6 +75,11 @@ EXTERN_C Thread* GetThread()
     return NULL;
 }
 
+Thread* GetThreadNULLOk()
+{
+    return GetThread();
+}
+
 BOOL
 DacGetThreadContext(Thread* thread, T_CONTEXT* context)
 {
index 6ae9eaf..ef833b1 100644 (file)
@@ -309,7 +309,7 @@ void HelperCanary::ThreadProc()
 //-----------------------------------------------------------------------------
 void HelperCanary::TakeLocks()
 {
-    _ASSERTE(::GetThread() == NULL); // Canary Thread should always be outside the runtime.
+    _ASSERTE(::GetThreadNULLOk() == NULL); // Canary Thread should always be outside the runtime.
     _ASSERTE(m_CanaryThreadId == GetCurrentThreadId());
 
     // Call new, which will take whatever standard heap locks there are.
index aa81d1b..7f7fb10 100644 (file)
@@ -3249,7 +3249,7 @@ void DebuggerController::UnapplyTraceFlag(Thread *thread)
     // Either this is the helper thread, or we're manipulating our own context.
     _ASSERTE(
         ThisIsHelperThreadWorker() ||
-        (thread == ::GetThread())
+        (thread == ::GetThreadNULLOk())
     );
 
     CONTEXT *context = GetManagedStoppedCtx(thread);
@@ -3324,7 +3324,7 @@ BOOL DebuggerController::DispatchExceptionHook(Thread *thread,
         MODE_ANY;
 
         // Filter context not set yet b/c we can only set it in COOP, and this may be in preemptive.
-        PRECONDITION(thread == ::GetThread());
+        PRECONDITION(thread == ::GetThreadNULLOk());
         PRECONDITION((g_pEEInterface->GetThreadFilterContext(thread) == NULL));
         PRECONDITION(CheckPointer(pException));
     }
@@ -4537,7 +4537,7 @@ void DebuggerPatchSkip::DebuggerDetachClean()
    // 2. Create a "stack walking" implementation for native code and use it to get the current IP and
    // set the IP to the right place.
 
-    Thread *thread = GetThread();
+    Thread *thread = GetThreadNULLOk();
     if (thread != NULL)
     {
         BYTE *patchBypass = m_pSharedPatchBypassBuffer->PatchBypass;
@@ -4672,7 +4672,7 @@ TP_RESULT DebuggerPatchSkip::TriggerExceptionHook(Thread *thread, CONTEXT * cont
         // toggled the GC mode underneath us.
         MODE_ANY;
 
-        PRECONDITION(GetThread() == thread);
+        PRECONDITION(GetThreadNULLOk() == thread);
         PRECONDITION(thread != NULL);
         PRECONDITION(CheckPointer(context));
     }
@@ -6597,8 +6597,6 @@ void DebuggerStepper::StepOut(FramePointer fp, StackTraceTicket ticket)
         "\n", fp.GetSPValue(), this ));
 
     Thread *thread = GetThread();
-
-
     CONTEXT *context = g_pEEInterface->GetThreadFilterContext(thread);
     ControllerStackInfo info;
 
@@ -7711,7 +7709,7 @@ bool DebuggerStepper::SendEvent(Thread *thread, bool fIpChanged)
     LOG((LF_CORDB, LL_INFO10000, "DS::SE m_fpStepInto:0x%x\n", m_fpStepInto.GetSPValue()));
 
     _ASSERTE(m_fReadyToSend);
-    _ASSERTE(GetThread() == thread);
+    _ASSERTE(GetThreadNULLOk() == thread);
 
     CONTEXT *context = g_pEEInterface->GetThreadFilterContext(thread);
     _ASSERTE(!ISREDIRECTEDTHREAD(thread));
index 095f591..d64bb94 100644 (file)
@@ -366,10 +366,10 @@ void Debugger::DoNotCallDirectlyPrivateLock(void)
     //
     Thread * pThread;
     bool fIsCooperative;
-    BEGIN_GETTHREAD_ALLOWED;
+    
     pThread = g_pEEInterface->GetThread();
     fIsCooperative = (pThread != NULL) && (pThread->PreemptiveGCDisabled());
-    END_GETTHREAD_ALLOWED;
+    
     if (m_fShutdownMode && !fIsCooperative)
     {
         // The big fear is that some other random thread will take the debugger-lock and then block on something else,
@@ -778,7 +778,7 @@ CONTEXT * GetManagedLiveCtx(Thread * pThread)
     // We're in some Controller's Filter after hitting an exception.
     // We're not stopped.
     //_ASSERTE(!g_pDebugger->IsStopped()); <-- @todo - this fires, need to find out why.
-    _ASSERTE(GetThread() == pThread);
+    _ASSERTE(GetThreadNULLOk() == pThread);
 
     CONTEXT *pCtx = g_pEEInterface->GetThreadFilterContext(pThread);
 
@@ -1113,70 +1113,6 @@ void Debugger::InitDebugEventCounting()
 #endif // _DEBUG
 }
 
-
-// This is a notification from the EE it's about to go to fiber mode.
-// This is given *before* it actually goes to fiber mode.
-HRESULT Debugger::SetFiberMode(bool isFiberMode)
-{
-    CONTRACTL
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-
-        // Notifications from EE never come on helper worker.
-        PRECONDITION(!ThisIsHelperThreadWorker());
-    }
-    CONTRACTL_END;
-
-
-    Thread * pThread = ::GetThread();
-
-    m_pRCThread->m_pDCB->m_bHostingInFiber = isFiberMode;
-
-    // If there is a debugger already attached, then we have a big problem. As of V2.0, the debugger
-    // does not support debugging processes with fibers in them. We set the unrecoverable state to
-    // indicate that we're in a bad state now. The debugger will notice this, and take appropiate action.
-    if (isFiberMode && CORDebuggerAttached())
-    {
-        LOG((LF_CORDB, LL_INFO10, "Thread has entered fiber mode while debugger attached.\n"));
-
-        EX_TRY
-        {
-            // We send up a MDA for two reasons: 1) we want to give the user some chance to see what went wrong,
-            // and 2) we want to get the Right Side to notice that we're in an unrecoverable error state now.
-
-            SString szName(W("DebuggerFiberModeNotSupported"));
-            SString szDescription;
-            szDescription.LoadResource(CCompRC::Debugging, MDARC_DEBUGGER_FIBER_MODE_NOT_SUPPORTED);
-            SString szXML(W(""));
-
-            // Sending any debug event will be a GC violation.
-            // However, if we're enabling fiber-mode while a debugger is attached, we're already doomed.
-            // Deadlocks and AVs are just around the corner. A Gc-violation is the least of our worries.
-            // We want to at least notify the debugger at all costs.
-            CONTRACT_VIOLATION(GCViolation);
-
-            // As soon as we set unrecoverable error in the LS,  the RS will pick it up and basically shut down.
-            // It won't dispatch any events. So we fire the MDA first, and then set unrecoverable error.
-            SendMDANotification(pThread, &szName, &szDescription, &szXML, (CorDebugMDAFlags) 0, FALSE);
-
-            CORDBDebuggerSetUnrecoverableError(this, CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS, false);
-
-            // Fire the MDA again just to force the RS to sniff the LS and pick up that we're in an unrecoverable error.
-            // No harm done from dispatching an MDA twice. And
-            SendMDANotification(pThread, &szName, &szDescription, &szXML, (CorDebugMDAFlags) 0, FALSE);
-
-        }
-        EX_CATCH
-        {
-            LOG((LF_CORDB, LL_INFO10, "Error sending MDA regarding fiber mode.\n"));
-        }
-        EX_END_CATCH(SwallowAllExceptions);
-    }
-
-    return S_OK;
-}
-
 // Checks if the MethodInfos table has been allocated, and if not does so.
 // Throw on failure, so we always return
 HRESULT Debugger::CheckInitMethodInfoTable()
@@ -1777,7 +1713,7 @@ void Debugger::SendCreateProcess(DebuggerLockHolder * pDbgLockHolder)
     // This ensures the debuggee is actually stopped at startup, and
     // this gives the debugger a chance to call SetDesiredNGENFlags before we
     // set s_fCanChangeNgenFlags to FALSE.
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
     SENDIPCEVENT_RAW_END;
 
     pDbgLockHolder->Acquire();
@@ -6154,7 +6090,7 @@ void Debugger::SendRawUserBreakpoint(Thread * pThread)
         GC_NOTRIGGER;
         MODE_PREEMPTIVE;
 
-        PRECONDITION(pThread == GetThread());
+        PRECONDITION(pThread == GetThreadNULLOk());
 
         PRECONDITION(ThreadHoldsLock());
 
@@ -7884,7 +7820,7 @@ void Debugger::ProcessAnyPendingEvals(Thread *pThread)
         DebuggerEval *pDE = pfe->pDE;
 
         _ASSERTE(pDE->m_evalDuringException);
-        _ASSERTE(pDE->m_thread == GetThread());
+        _ASSERTE(pDE->m_thread == GetThreadNULLOk());
 
         // Remove the pending eval from the hash. This ensures that if we take a first chance exception during the eval
         // that we can do another nested eval properly.
@@ -7936,7 +7872,7 @@ bool Debugger::FirstChanceManagedException(Thread *pThread, SIZE_T currentIP, SI
 
     LOG((LF_CORDB, LL_INFO10000, "D::FCE: First chance exception, TID:0x%x, \n", GetThreadIdHelper(pThread)));
 
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
 
 #ifdef _DEBUG
     static ConfigDWORD d_fce;
@@ -7980,7 +7916,7 @@ void Debugger::FirstChanceManagedExceptionCatcherFound(Thread *pThread,
     // @@@
     // Implements DebugInterface
     // Call by EE/exception. Must be on managed thread
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
 
     // Quick check.
     if (!CORDebuggerAttached())
@@ -8048,7 +7984,7 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p
 {
     CONTRACTL
     {
-        if ((GetThread() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
+        if ((GetThreadNULLOk() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
         {
             NOTHROW;
             GC_NOTRIGGER;
@@ -8080,7 +8016,7 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p
     // useful information for the debugger and, in fact, it may be a completely
     // internally handled runtime exception, so we should do nothing.
     //
-    if ((GetThread() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
+    if ((GetThreadNULLOk() == NULL) || g_pEEInterface->IsThreadExceptionNull(GetThread()))
     {
         return EXCEPTION_CONTINUE_SEARCH;
     }
@@ -8958,7 +8894,7 @@ void Debugger::SendUserBreakpoint(Thread * thread)
         MODE_ANY;
 
         PRECONDITION(thread != NULL);
-        PRECONDITION(thread == ::GetThread());
+        PRECONDITION(thread == ::GetThreadNULLOk());
     }
     CONTRACTL_END;
 
@@ -14815,7 +14751,7 @@ HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain)
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
index b4086fe..52ed736 100644 (file)
@@ -2351,7 +2351,6 @@ public:
         if (g_fProcessDetach)
             return true;
 
-        BEGIN_GETTHREAD_ALLOWED;
         if (g_pEEInterface->GetThread())
         {
             return (GetThreadIdHelper(g_pEEInterface->GetThread()) == m_mutexOwner);
@@ -2360,7 +2359,6 @@ public:
         {
             return (GetCurrentThreadId() == m_mutexOwner);
         }
-        END_GETTHREAD_ALLOWED;
     }
 #endif // _DEBUG_IMPL
 
@@ -2514,7 +2512,6 @@ public:
 
     BOOL ShouldAutoAttach();
     BOOL FallbackJITAttachPrompt();
-    HRESULT SetFiberMode(bool isFiberMode);
 
     HRESULT AddAppDomainToIPC (AppDomain *pAppDomain);
     HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain);
@@ -3912,7 +3909,7 @@ HANDLE OpenWin32EventOrThrow(
       if ((m_pRCThread == NULL) || !m_pRCThread->IsRCThreadReady()) { THROWS; } else { NOTHROW; }
 
 #define MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT \
-      if ((m_pRCThread == NULL) || !m_pRCThread->IsRCThreadReady() || (GetThread() != NULL)) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
+      if ((m_pRCThread == NULL) || !m_pRCThread->IsRCThreadReady() || (GetThreadNULLOk() != NULL)) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
 
 #define GC_TRIGGERS_FROM_GETJITINFO if (GetThreadNULLOk() != NULL) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
 
index 011c7a1..d05a0db 100644 (file)
@@ -1957,7 +1957,7 @@ bool ShouldSendUMLeafChain(Thread * pThread)
 
     // If we're tracing ourselves, we must be in managed code.
     // Native user code can't initiate a managed stackwalk.
-    if (pThread == GetThread())
+    if (pThread == GetThreadNULLOk())
     {
         return false;
     }
@@ -2008,7 +2008,7 @@ bool PrepareLeafUMChain(DebuggerFrameData * pData, CONTEXT * pCtxTemp)
 
         // We need to get thread's context (InitRegDisplay will do that under the covers).
         // If this is our thread, we're in bad shape. Fortunately that should never happen.
-        _ASSERTE(thread != GetThread());
+        _ASSERTE(thread != GetThreadNULLOk());
 
         Thread::SuspendThreadResult str = thread->SuspendThread();
         if (str != Thread::STR_Success)
index 68fea02..a50c09e 100644 (file)
 //                              then it's ok for this function to as well.  If LIMITED_METHOD_CONTRACT is specified,
 //                              however, then CANNOT_TAKE_LOCK is assumed.
 //
-//      EE_THREAD_NOT_REQUIRED  the function does not assume an EE Thread object is available in TLS.
-//                              Either GetThread() is never called, or any code path that requires a Thread
-//                              has another code path that deals with the absence of a Thread.  Any call to
-//                              to GetThread() must be bracketed with BEGIN_GETTHREAD_ALLOWED /
-//                              END_GETTHREAD_ALLOWED to avoid bogus asserts (the short-form
-//                              GetThreadNULLOk() may be used as well).  However, this is only allowed if visual
-//                              inspection of the call site makes it patently obvious that the function deals
-//                              appropriately with the GetThread() == NULL case.
-//      -or- EE_THREAD_REQUIRED the function requires an EE Thread object in TLS (i.e., GetThread() != NULL)
-//                              If this contract is used, we will ASSERT on entry to the function that
-//                              GetThread() != NULL.
-//      -or-                    the default is DISABLED(EE_THREAD_REQUIRED).  i.e., we do not assert
-//                              GetThread() != NULL on entry to the function and do not assert on any
-//                              unprotected uses of GetThread().
-//                              See code:GetThreadGenericFullCheck for info on how these
-//                              contracts are enforced.
 //
 //      SUPPORTS_DAC            The function has been written to be callable from out-of-process using DAC.
 //                              In builds where DACCESS_COMPILE is defined, such functions can only call
@@ -398,9 +382,8 @@ public:
 #define CONTRACT_BITMASK_SOTOLERANT           0x1 << 3
 #define CONTRACT_BITMASK_DEBUGONLY            0x1 << 4
 #define CONTRACT_BITMASK_SONOTMAINLINE        0x1 << 5
-#define CONTRACT_BITMASK_ALLOWGETTHREAD       0x1 << 6
-#define CONTRACT_BITMASK_OK_TO_LOCK           0x1 << 7
-#define CONTRACT_BITMASK_OK_TO_RETAKE_LOCK    0x1 << 8
+#define CONTRACT_BITMASK_OK_TO_LOCK           0x1 << 6
+#define CONTRACT_BITMASK_OK_TO_RETAKE_LOCK    0x1 << 7
 
 
 #define CONTRACT_BITMASK_IS_SET(whichbit)    ((m_flags & (whichbit)) != 0)
@@ -441,7 +424,6 @@ public:
         m_flags             = CONTRACT_BITMASK_OK_TO_THROW|
                               CONTRACT_BITMASK_HOSTCALLS|
                               CONTRACT_BITMASK_SOTOLERANT|
-                              CONTRACT_BITMASK_ALLOWGETTHREAD|
                               CONTRACT_BITMASK_OK_TO_LOCK|
                               CONTRACT_BITMASK_OK_TO_RETAKE_LOCK;
 
@@ -582,30 +564,6 @@ public:
     }
 
     //--//
-    BOOL IsGetThreadAllowed()
-    {
-        return CONTRACT_BITMASK_IS_SET(CONTRACT_BITMASK_ALLOWGETTHREAD);
-
-    }
-    void SetGetThreadAllowed()
-    {
-        CONTRACT_BITMASK_SET(CONTRACT_BITMASK_ALLOWGETTHREAD);
-    }
-
-
-     BOOL SetGetThreadAllowed(BOOL value)
-    {
-        BOOL prevState = CONTRACT_BITMASK_IS_SET(CONTRACT_BITMASK_ALLOWGETTHREAD);
-        CONTRACT_BITMASK_UPDATE(CONTRACT_BITMASK_ALLOWGETTHREAD,value);
-        return prevState;
-    }
-
-    void ResetGetThreadAllowed()
-    {
-        CONTRACT_BITMASK_RESET(CONTRACT_BITMASK_ALLOWGETTHREAD);
-    }
-
-    //--//
     BOOL IsOkToLock()
     {
         return CONTRACT_BITMASK_IS_SET(CONTRACT_BITMASK_OK_TO_LOCK);
@@ -944,17 +902,6 @@ class BaseContract
         HOST_NoCalls            = 0x00001000,
         HOST_Disabled           = 0x00000000,   // the default
 
-        // This enforces the EE_THREAD_NOT_REQUIRED contract by clearing
-        // ClrDebugState::m_allowGetThread in its scope.  That causes raw calls
-        // to GetThread() to assert, unless inside a temporary "don't worry it's ok" scope
-        // via BEGIN/END_GETTHREAD_ALLOWED.  Useful for enforcing our docs that
-        // state certain unmanaged API entrypoints (e.g., some from profiling API)
-        // are callable without an EE Thread in TLS.
-        EE_THREAD_Mask          = 0x0000C000,
-        EE_THREAD_Disabled      = 0x00000000,   // the default
-        EE_THREAD_Required      = 0x00004000,
-        EE_THREAD_Not_Required  = 0x00008000,
-
         // These enforce the CAN_TAKE_LOCK / CANNOT_TAKE_LOCK contracts
         CAN_TAKE_LOCK_Mask      = 0x00060000,
         CAN_TAKE_LOCK_Yes       = 0x00020000,
@@ -973,7 +920,7 @@ class BaseContract
         LOADS_TYPE_Disabled     = 0x00000000,   // the default
 
         ALL_Disabled            = THROWS_Disabled|GC_Disabled|FAULT_Disabled|MODE_Disabled|LOADS_TYPE_Disabled|
-                                  HOST_Disabled|EE_THREAD_Disabled|CAN_TAKE_LOCK_Disabled|CAN_RETAKE_LOCK_No_Disabled
+                                  HOST_Disabled|CAN_TAKE_LOCK_Disabled|CAN_RETAKE_LOCK_No_Disabled
 
     };
 
@@ -1178,7 +1125,6 @@ enum ContractViolationBits
     LoadsTypeViolation      = 0x00000040,  // suppress LOADS_TYPE tags in this scope
     TakesLockViolation      = 0x00000080,  // suppress CAN_TAKE_LOCK tags in this scope
     HostViolation           = 0x00000100,  // suppress HOST_CALLS tags in this scope
-    EEThreadViolation       = 0x00000200,  // suppress EE_THREAD_REQUIRED tags in this scope
 
     //These are not violation bits. We steal some bits out of the violation mask to serve as
     // general flag bits.
@@ -2106,68 +2052,6 @@ class HostNoCallHolder
     }
 #endif
 
-#ifdef ENABLE_CONTRACTS_IMPL
-
-class GetThreadAllowedHolder
-{
-    public:
-    GetThreadAllowedHolder(BOOL newState)
-        {
-        m_clrDebugState = ::GetClrDebugState();
-        m_previousState = m_clrDebugState->SetGetThreadAllowed(newState);
-        }
-
-    ~GetThreadAllowedHolder()
-        {
-        m_clrDebugState->SetGetThreadAllowed(m_previousState);
-        }
-
-private:
-    BOOL m_previousState;
-    ClrDebugState* m_clrDebugState;
-};
-
-// When in an EE_THREAD_NOT_REQUIRED contracted scope, it's expected that the
-// function does not assume an EE Thread object is available in TLS.  Either
-// GetThread() is never called, or any code path that requires a Thread
-// has another code path that deals with the absence of a Thread.  Any call to
-// to GetThread() must be bracketed with BEGIN_GETTHREAD_ALLOWED /
-// END_GETTHREAD_ALLOWED to avoid bogus asserts (the short-form
-// GetThreadNULLOk() may be used as well).  However, this is only allowed if visual
-// inspection of the call site makes it patently obvious that the function deals
-// appropriately with the GetThread() == NULL case (or that case has already been
-// dealt with and control has exited before the BEGIN_GETTHREAD_ALLOWED /
-// END_GETTHREAD_ALLOWED block.
-//
-// These use holder objects, which causes the compiler to generate EH code and prevent
-// inlining.  So try to avoid these in small, downstream functions (like inline
-// EE Thread member functions).  Use the _IN_NO_THROW_REGION variants below instead.
-
-#define BEGIN_GETTHREAD_ALLOWED                                                 \
-    {                                                                           \
-        GetThreadAllowedHolder __getThreadAllowedHolder(TRUE);                  \
-
-#define END_GETTHREAD_ALLOWED                                                   \
-    }
-
-// These are lighter-weight versions of BEGIN_GETTHREAD_ALLOWED /
-// END_GETTHREAD_ALLOWED.  These don't use holders, so be sure only to
-// use these to bracket code that won't throw exceptions
-#define BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION                                       \
-    {                                                                                       \
-        ClrDebugState * __clrDebugState = ::GetClrDebugState();                   \
-        BOOL __previousState = __clrDebugState->SetGetThreadAllowed(TRUE);      \
-
-#define END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION                                         \
-        __clrDebugState->SetGetThreadAllowed(__previousState);                  \
-    }
-
-#else // ENABLE_CONTRACTS_IMPL
-#define BEGIN_GETTHREAD_ALLOWED
-#define END_GETTHREAD_ALLOWED
-#define BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION
-#define END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION
-#endif
 
 #if defined(ENABLE_CONTRACTS_IMPL)
 
index d7d0678..d97fad1 100644 (file)
@@ -719,7 +719,7 @@ private:
 // Special define to be used in EEStartup that will also check for VM initialization before
 // commencing on a path that may use the managed thread object.
 #define RethrowTerminalExceptionsWithInitCheck  \
-    if ((g_fEEStarted == TRUE) && (GetThread() != NULL))    \
+    if ((g_fEEStarted == TRUE) && (GetThreadNULLOk() != NULL))    \
     {                                                       \
         RethrowTerminalExceptions                           \
     }
index 5c93b03..17b9c4e 100644 (file)
@@ -573,7 +573,7 @@ AdjustContextForVirtualStub(
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     // We may not have a managed thread object. Example is an AV on the helper thread.
     // (perhaps during StubManager::IsStub)
index e76b6d4..38bff78 100644 (file)
@@ -280,7 +280,7 @@ PBYTE WriteBarrierManager::CalculatePatchLocation(LPVOID base, LPVOID label, int
 
 int WriteBarrierManager::ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier, bool isRuntimeSuspended)
 {
-    GCX_MAYBE_COOP_NO_THREAD_BROKEN((!isRuntimeSuspended && GetThread() != NULL));
+    GCX_MAYBE_COOP_NO_THREAD_BROKEN((!isRuntimeSuspended && GetThreadNULLOk() != NULL));
     int stompWBCompleteActions = SWB_PASS;
     if (!isRuntimeSuspended && m_currentWriteBarrier != WRITE_BARRIER_UNINITIALIZED)
     {
index c6febd2..6c57f87 100644 (file)
@@ -161,7 +161,7 @@ NESTED_ENTRY JIT_PInvokeBegin, _TEXT, NoHandler
         mov             r14, rdi
 
         // Get current thread and cache it in current frame
-        call            C_FUNC(GetThread)
+        call            C_FUNC(GetThreadHelper)
         mov             qword ptr [r14 + OFFSETOF__InlinedCallFrame__m_pThread], rax
 
         // pFrame->m_Next = pThread->m_pFrame;
index f5271cc..46aa6f3 100644 (file)
@@ -1115,7 +1115,7 @@ void SystemDomain::DetachBegin()
     // yet).
 
     // TODO: we should really not running managed DLLMain during process detach.
-    if (GetThread() == NULL)
+    if (GetThreadNULLOk() == NULL)
     {
         return;
     }
@@ -1611,8 +1611,6 @@ void SystemDomain::SetThreadAptState (Thread::ApartmentState state)
     STANDARD_VM_CONTRACT;
 
     Thread* pThread = GetThread();
-    _ASSERTE(pThread);
-
     if(state == Thread::AS_InSTA)
     {
         Thread::ApartmentState pState = pThread->SetApartment(Thread::AS_InSTA);
@@ -3548,7 +3546,7 @@ void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName, BOOL fDebuggerCares/*=T
     CONTRACTL
     {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
         INJECT_FAULT(COMPlusThrowOM(););
     }
@@ -3602,7 +3600,7 @@ LPCWSTR AppDomain::GetFriendlyName(BOOL fDebuggerCares/*=TRUE*/)
     CONTRACT (LPCWSTR)
     {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
         POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
         INJECT_FAULT(COMPlusThrowOM(););
@@ -3633,7 +3631,7 @@ LPCWSTR AppDomain::GetFriendlyNameForDebugger()
     CONTRACT (LPCWSTR)
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
         POSTCONDITION(CheckPointer(RETVAL));
     }
@@ -4537,7 +4535,6 @@ void AppDomain::ExceptionUnwind(Frame *pFrame)
 
     LOG((LF_APPDOMAIN, LL_INFO10, "AppDomain::ExceptionUnwind for %8.8x\n", pFrame));
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
 
     LOG((LF_APPDOMAIN, LL_INFO10, "AppDomain::ExceptionUnwind: not first transition or abort\n"));
 }
index de75885..9fff8b4 100644 (file)
@@ -864,7 +864,7 @@ public:
     void Activate()
     {
         WRAPPER_NO_CONTRACT;
-        m_previousLimit=GetThread()->GetLoadLevelLimiter();
+        m_previousLimit= GetThread()->GetLoadLevelLimiter();
         if(m_previousLimit)
             m_currentLevel=m_previousLimit->GetLoadLevel();
         GetThread()->SetLoadLevelLimiter(this);
index d82646c..59d61b0 100644 (file)
@@ -61,7 +61,7 @@ AdjustContextForVirtualStub(
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     // We may not have a managed thread object. Example is an AV on the helper thread.
     // (perhaps during StubManager::IsStub)
index 483816c..8e7c468 100644 (file)
         str     r9, [r4, #InlinedCallFrame__m_pSPAfterProlog]
 
         // r0 = GetThread()
-        bl      C_FUNC(GetThread)
+        bl      C_FUNC(GetThreadHelper)
         str     r0, [r4, #InlinedCallFrame__m_pThread]
 
         // pFrame->m_Next = pThread->m_pFrame;
index d41eb94..1ca6fd0 100644 (file)
@@ -1398,7 +1398,7 @@ void StubLinkerCPU::ThumbEmitGetThread(ThumbReg dest)
 {
 #ifdef TARGET_UNIX
 
-    ThumbEmitMovConstant(ThumbReg(0), (TADDR)GetThread);
+    ThumbEmitMovConstant(ThumbReg(0), (TADDR)GetThreadHelper);
 
     ThumbEmitCallRegister(ThumbReg(0));
 
index ff16e14..e10b811 100644 (file)
@@ -118,7 +118,7 @@ LOCAL_LABEL(\__PInvokeStubFuncName\()_0):
         str     x9, [x19, #InlinedCallFrame__m_pCalleeSavedFP]
 
         // x0 = GetThread()
-        bl      C_FUNC(GetThread)
+        bl      C_FUNC(GetThreadHelper)
         str     x0, [x19, #InlinedCallFrame__m_pThread]
 
         // pFrame->m_Next = pThread->m_pFrame;
index f91778c..acacdf8 100644 (file)
@@ -1154,7 +1154,7 @@ AdjustContextForVirtualStub(
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     // We may not have a managed thread object. Example is an AV on the helper thread.
     // (perhaps during StubManager::IsStub)
index 5d7de0f..a8569c0 100644 (file)
@@ -1559,7 +1559,7 @@ static void RunMainPre()
 {
     LIMITED_METHOD_CONTRACT;
 
-    _ASSERTE(GetThread() != 0);
+    _ASSERTE(GetThreadNULLOk() != 0);
     g_fWeControlLifetime = TRUE;
 }
 
@@ -1571,7 +1571,7 @@ static void RunMainPost()
         GC_TRIGGERS;
         MODE_ANY;
         INJECT_FAULT(COMPlusThrowOM(););
-        PRECONDITION(CheckPointer(GetThread()));
+        PRECONDITION(CheckPointer(GetThreadNULLOk()));
     }
     CONTRACTL_END
 
index 3dbd866..25c4f54 100644 (file)
@@ -480,13 +480,13 @@ void CoreLibBinder::TriggerGCUnderStress()
     CONTRACTL_END;
 
 #ifndef DACCESS_COMPILE
-    _ASSERTE (GetThread ());
+    _ASSERTE (GetThreadNULLOk());
     TRIGGERSGC ();
     // Force a GC here because GetClass could trigger GC nondeterminsticly
     if (g_pConfig->GetGCStressLevel() != 0)
     {
         DEBUG_ONLY_REGION();
-        Thread * pThread = GetThread ();
+        Thread * pThread = GetThread();
         BOOL bInCoopMode = pThread->PreemptiveGCDisabled ();
         GCX_COOP ();
         if (bInCoopMode)
index dfecf88..1a19c43 100644 (file)
@@ -822,7 +822,7 @@ void CallCountingManager::CompleteCallCounting()
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() == TieredCompilationManager::GetBackgroundWorkerThread());
+    _ASSERTE(GetThreadNULLOk() == TieredCompilationManager::GetBackgroundWorkerThread());
 
     AppDomain *appDomain = GetAppDomain();
     TieredCompilationManager *tieredCompilationManager = appDomain->GetTieredCompilationManager();
@@ -943,7 +943,7 @@ void CallCountingManager::StopAndDeleteAllCallCountingStubs()
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() == TieredCompilationManager::GetBackgroundWorkerThread());
+    _ASSERTE(GetThreadNULLOk() == TieredCompilationManager::GetBackgroundWorkerThread());
 
     // If a number of call counting stubs have completed, we can try to delete them to reclaim some memory. Deleting
     // involves suspending the runtime and will delete all call counting stubs, and after that some call counting stubs may
@@ -1001,7 +1001,7 @@ void CallCountingManager::StopAllCallCounting(TieredCompilationManager *tieredCo
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() == TieredCompilationManager::GetBackgroundWorkerThread());
+    _ASSERTE(GetThreadNULLOk() == TieredCompilationManager::GetBackgroundWorkerThread());
     _ASSERTE(MethodDescBackpatchInfoTracker::IsLockOwnedByCurrentThread());
     _ASSERTE(CodeVersionManager::IsLockOwnedByCurrentThread());
     _ASSERTE(tieredCompilationManager != nullptr);
index d5493b6..fa32e4e 100644 (file)
@@ -106,7 +106,6 @@ void CallDescrWorker(CallDescrData * pCallDescrData)
     DWORD_PTR ObjRefTable[OBJREF_TABSIZE];
 
     curThread = GetThread();
-    _ASSERTE(curThread != NULL);
 
     static_assert_no_msg(sizeof(curThread->dangerousObjRefs) == sizeof(ObjRefTable));
     memcpy(ObjRefTable, curThread->dangerousObjRefs, sizeof(ObjRefTable));
index 3561f0e..62926cd 100644 (file)
@@ -1206,7 +1206,7 @@ void WaitForEndOfShutdown()
     // We are shutting down.  GC triggers does not have any effect now.
     CONTRACT_VIOLATION(GCViolation);
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     // After a thread is blocked in WaitForEndOfShutdown, the thread should not enter runtime again,
     // and block at WaitForEndOfShutdown again.
     if (pThread)
@@ -1259,7 +1259,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
 
 #if defined(FEATURE_COMINTEROP)
     // Get the current thread.
-    Thread * pThisThread = GetThread();
+    Thread * pThisThread = GetThreadNULLOk();
 #endif
 
     // If the process is detaching then set the global state.
@@ -1718,7 +1718,7 @@ void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading)
 #endif
     }
 
-    if (GetThread())
+    if (GetThreadNULLOk())
     {
         GCX_COOP();
         EEShutDownHelper(fIsDllUnloading);
@@ -1896,7 +1896,7 @@ struct TlsDestructionMonitor
         // Don't destroy threads here if we're in shutdown (shutdown will
         // clean up for us instead).
 
-        Thread* thread = GetThread();
+        Thread* thread = GetThreadNULLOk();
         if (thread)
         {
 #ifdef FEATURE_COMINTEROP
@@ -2074,7 +2074,7 @@ static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
         InlineSString<LOCALE_NAME_MAX_LENGTH> sParentCulture;
 
 #if 0 // Enable and test if/once the unmanaged runtime is localized
-        Thread * pThread = GetThread();
+        Thread * pThread = GetThreadNULLOk();
 
         // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
         // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
@@ -2203,7 +2203,7 @@ static int GetThreadUICultureId(__out LocaleIDValue* pLocale)
 
     int Result = 0;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
 #if 0 // Enable and test if/once the unmanaged runtime is localized
     // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
index 4f00fbf..93d5d44 100644 (file)
@@ -607,9 +607,6 @@ VOID MethodTableBuilder::BuildInteropVTable_InterfaceList(
     *pcBuildingInterfaceList = 0;
     *ppBuildingInterfaceList = NULL;
 
-    // Get the thread for stacking allocator
-    Thread *pThread = GetThread();
-
     // Get the metadata for enumerating the interfaces of the class
     IMDInternalImport *pMDImport = GetModule()->GetMDImport();
 
@@ -1048,7 +1045,6 @@ VOID MethodTableBuilder::BuildInteropVTable_ResolveInterfaces(
 
     HRESULT hr = S_OK;
     DWORD i;
-    Thread *pThread = GetThread();
 
     // resolve unresolved interfaces, determine an upper bound on the size of the interface map,
     // and determine the size of the largest interface (in # slots)
@@ -1754,7 +1750,6 @@ VOID MethodTableBuilder::BuildInteropVTable_PlaceInterfaceDeclaration(
                 // laying out the method table.
                 if(bmtInterface->pdwOriginalStart == NULL)
                 {
-                    Thread *pThread = GetThread();
                     bmtInterface->pdwOriginalStart = new (GetStackingAllocator()) DWORD[bmtInterface->dwMaxExpandedInterfaces];
                     memset(bmtInterface->pdwOriginalStart, 0, sizeof(DWORD)*bmtInterface->dwMaxExpandedInterfaces);
                 }
index 8e4e1e9..aca0fe2 100644 (file)
@@ -622,10 +622,8 @@ OBJECTREF CLRException::GetThrowableFromException(Exception *pException)
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();
-
     // Can't have a throwable without a Thread.
-    _ASSERTE(pThread != NULL);
+    Thread* pThread = GetThread();
 
     if (NULL == pException)
     {
@@ -814,7 +812,7 @@ void CLRException::HandlerState::CleanupTry()
 
     if (m_pThread != NULL)
     {
-        BEGIN_GETTHREAD_ALLOWED;
+        
         // If there is no frame to unwind, UnwindFrameChain call is just an expensive NOP
         // due to setting up and tear down of EH records. So we avoid it if we can.
         if (m_pThread->GetFrame() < m_pFrame)
@@ -827,7 +825,7 @@ void CLRException::HandlerState::CleanupTry()
             else
                 m_pThread->EnablePreemptiveGC();
         }
-        END_GETTHREAD_ALLOWED;
+        
     }
 
     // Make sure to call the base class's CleanupTry so it can do whatever it wants to do.
@@ -848,7 +846,7 @@ void CLRException::HandlerState::SetupCatch(INDEBUG_COMMA(__in_z const char * sz
 
     if (g_fEEStarted)
     {
-        pThread = GetThread();
+        pThread = GetThreadNULLOk();
         exceptionCode = GetCurrentExceptionCode();
     }
 
@@ -1359,7 +1357,7 @@ OBJECTREF EEArgumentException::CreateThrowable()
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
 
     ProtectArgsStruct prot;
     memset(&prot, 0, sizeof(ProtectArgsStruct));
@@ -2237,7 +2235,7 @@ void GetLastThrownObjectExceptionFromThread(Exception **ppException)
     CONTRACTL_END;
 
     // If the Thread has been set up, then the LastThrownObject may make sense...
-    if (GetThread())
+    if (GetThreadNULLOk())
     {
         // give back an object that knows about Threads and their exceptions.
         *ppException = new CLRLastThrownObjectException();
index 2ed24e1..2bdf824 100644 (file)
@@ -752,7 +752,7 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv);
 #define PAL_SEH_RESTORE_GUARD_PAGE                                                  \
     if (__exCode == STATUS_STACK_OVERFLOW)                                          \
     {                                                                               \
-        Thread *__pThread = GetThread();                                            \
+        Thread *__pThread = GetThreadNULLOk();                                            \
         if (__pThread != NULL)                                                      \
         {                                                                           \
             __pThread->RestoreGuardPage();                                          \
@@ -799,7 +799,7 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv);
             STRESS_LOG1(LF_EH, LL_INFO100,                                              \
                 "EX_RETHROW " INDEBUG(__FILE__) " line %d\n", __LINE__);                \
             __pException.SuppressRelease();                                             \
-            if ((!__state.DidCatchCxx()) && (GetThread() != NULL))                      \
+            if ((!__state.DidCatchCxx()) && (GetThreadNULLOk() != NULL))                      \
             {                                                                           \
                 if (GetThread()->PreemptiveGCDisabled())                                \
                 {                                                                       \
@@ -908,7 +908,7 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv);
     {                                                               \
         HRESULT *__phr = (phresult);                                \
         *__phr = S_OK;                                              \
-        _ASSERTE(GetThread() == NULL ||                             \
+        _ASSERTE(GetThreadNULLOk() == NULL ||                             \
                     !GetThread()->PreemptiveGCDisabled());          \
         MAKE_CURRENT_THREAD_AVAILABLE_EX(GetThreadNULLOk());        \
         if (CURRENT_THREAD == NULL)                                 \
index 26ae406..edf5d64 100644 (file)
@@ -836,7 +836,7 @@ TADDR ComPlusCall::GetFrameCallIP(FramedMethodFrame *frame)
 
 #ifndef DACCESS_COMPILE
 
-    Thread* thread = GetThread();
+    Thread* thread = GetThreadNULLOk();
     if (thread == NULL)
     {
         //
index 5802538..6569222 100644 (file)
@@ -214,7 +214,7 @@ PTR_Module ClassLoader::ComputeLoaderModuleForCompilation(
     // If this instantiation doesn't have a unique home then use the ngen module
 
     // OK, we're certainly NGEN'ing.  And if we're NGEN'ing then we're not on the debugger thread.
-    CONSISTENCY_CHECK(((GetThread() && GetAppDomain()) || IsGCThread()) &&
+    CONSISTENCY_CHECK(((GetThreadNULLOk() && GetAppDomain()) || IsGCThread()) &&
         "unexpected: running a load on debug thread but IsCompilationProcess() returned TRUE");
 
     // Save it into its PreferredZapModule if it's always going to be saved there.
index 23032b2..d0d4d58 100644 (file)
@@ -951,9 +951,9 @@ ExecutionManager::ScanFlag ExecutionManager::GetScanFlags()
     } CONTRACTL_END;
 
 #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-    BEGIN_GETTHREAD_ALLOWED;
+    
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     if (!pThread)
         return ScanNoReaderLock;
@@ -966,7 +966,7 @@ ExecutionManager::ScanFlag ExecutionManager::GetScanFlags()
     if (pThread->PreemptiveGCDisabled() || (pThread == ThreadSuspend::GetSuspensionThread()))
         return ScanNoReaderLock;
 
-    END_GETTHREAD_ALLOWED;
+    
 
     return ScanReaderLock;
 #else
index 689b641..bdfb344 100644 (file)
@@ -310,7 +310,6 @@ CtxEntry* CtxEntryCache::CreateCtxEntry(LPVOID pCtxCookie, Thread * pSTAThread)
     CONTRACTL_END;
 
     CtxEntry * pCtxEntry = NULL;
-    Thread * pThread = GetThread();
 
     // If we don't already have a context entry for the context cookie,
     // we need to create one.
@@ -374,7 +373,7 @@ CtxEntry* CtxEntryCache::FindCtxEntry(LPVOID pCtxCookie, Thread *pThread)
             pSTAThread = pThread;
     }
 
-    ASSERT (GetThread ());
+    ASSERT (GetThreadNULLOk ());
     BOOL bFound = FALSE;
 
     ACQUIRE_SPINLOCK_NO_HOLDER(&m_Lock);
@@ -542,7 +541,7 @@ VOID IUnkEntry::Free()
     CONTRACTL_END;
 
     // Log the de-allocation of the IUnknown entry.
-    LOG((LF_INTEROP, LL_INFO10000, "IUnkEntry::Free called for context 0x%08X, to release entry with m_pUnknown %p, on thread %p\n", m_pCtxCookie, m_pUnknown, GetThread()));
+    LOG((LF_INTEROP, LL_INFO10000, "IUnkEntry::Free called for context 0x%08X, to release entry with m_pUnknown %p, on thread %p\n", m_pCtxCookie, m_pUnknown, GetThreadNULLOk()));
 
     if (g_fProcessDetach)
     {
@@ -1386,7 +1385,7 @@ HRESULT __stdcall CtxEntry::EnterContextCallback(ComCallData* pComCallData)
     CtxEntryEnterContextCallbackData *pData = (CtxEntryEnterContextCallbackData*)pComCallData->pUserDefined;
 
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     // Make sure the thread has been set before we call the user callback function.
     if (!pThread)
index 962c041..a04ddc9 100644 (file)
@@ -103,7 +103,7 @@ void COMInterfaceMarshaler::CreateObjectRef(BOOL fDuplicate, OBJECTREF *pComObj,
         PRECONDITION(IsProtectedByGCFrame(pComObj));
         PRECONDITION(!m_typeHandle.IsNull());
         PRECONDITION(m_typeHandle.IsComObjectType());
-        PRECONDITION(m_pThread == GetThread());
+        PRECONDITION(m_pThread == GetThreadNULLOk());
         PRECONDITION(pIncomingItfMT == NULL || pIncomingItfMT->IsInterface());
     }
     CONTRACTL_END;
@@ -306,7 +306,7 @@ OBJECTREF COMInterfaceMarshaler::FindOrCreateObjectRefInternal(IUnknown **ppInco
         THROWS;
         GC_TRIGGERS;
         MODE_COOPERATIVE;
-        PRECONDITION(m_pThread == GetThread());
+        PRECONDITION(m_pThread == GetThreadNULLOk());
         PRECONDITION(pIncomingItfMT == NULL || pIncomingItfMT->IsInterface());
     }
     CONTRACTL_END;
index 6694e74..ce97e5a 100644 (file)
@@ -181,7 +181,11 @@ typedef PTR_Object OBJECTREF;
 typedef DPTR(OBJECTREF) PTR_OBJECTREF;
 typedef DPTR(PTR_OBJECTREF) PTR_PTR_OBJECTREF;
 
-EXTERN_C Thread* STDCALL GetThread();
+Thread* GetThread();
+Thread* GetThreadNULLOk();
+
+EXTERN_C Thread* STDCALL GetThreadHelper();
+
 void SetThread(Thread*);
 
 // This is a mechanism by which macros can make the Thread pointer available to inner scopes
index 8c5bef6..942c6be 100644 (file)
@@ -107,7 +107,7 @@ HRESULT CEECompileInfo::Startup(  BOOL fForceDebug,
     //
     if (SUCCEEDED(hr)) {
 #ifdef _DEBUG
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         _ASSERTE(pThread);
 #endif
 
index b596aa3..f3aac0e 100644 (file)
@@ -366,7 +366,6 @@ FCIMPL0(FC_BOOL_RET, ThreadPoolNative::NotifyRequestComplete)
     // we need a thread adjustment, before setting up the frame.
     //
     Thread *pThread = GetThread();
-    _ASSERTE (pThread);
 
     INT32 priority = pThread->ResetManagedThreadObjectInCoopMode(ThreadNative::PRIORITY_NORMAL);
 
@@ -469,7 +468,7 @@ RegisterWaitForSingleObjectCallback_Worker(LPVOID ptr)
 
 VOID NTAPI RegisterWaitForSingleObjectCallback(PVOID delegateInfo, BOOLEAN TimerOrWaitFired)
 {
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         ClrFlsSetThreadType(ThreadType_Threadpool_Worker);
@@ -529,7 +528,6 @@ FCIMPL5(LPVOID, ThreadPoolNative::CorRegisterWaitForSingleObject,
     _ASSERTE(hWaitHandle);
 
     Thread* pCurThread = GetThread();
-    _ASSERTE( pCurThread);
 
     DelegateInfoHolder delegateInfo = DelegateInfo::MakeDelegateInfo(
                                                                 &gc.state,
@@ -781,7 +779,7 @@ void __stdcall BindIoCompletionCallbackStubEx(DWORD ErrorCode,
                                               LPOVERLAPPED lpOverlapped,
                                               BOOL setStack)
 {
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         // TODO: how do we notify user of OOM here?
@@ -913,7 +911,7 @@ void AppDomainTimerCallback_Worker(LPVOID ptr)
 
 VOID WINAPI AppDomainTimerCallback(PVOID callbackState, BOOLEAN timerOrWaitFired)
 {
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         // TODO: how do we notify user of OOM here?
index 0a5be3c..4aa45af 100644 (file)
@@ -505,7 +505,7 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
     //
     HRESULT hr = S_OK;
 
-    pThread = GetThread();
+    pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         pThread = SetupThreadNoThrow();
index d8004a3..fec65f9 100644 (file)
@@ -522,8 +522,6 @@ FCIMPL0(EXCEPTION_POINTERS*, ExceptionNative::GetExceptionPointers)
     EXCEPTION_POINTERS* retVal = NULL;
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
     if (pThread->IsExceptionInProgress())
     {
         retVal = pThread->GetExceptionState()->GetExceptionPointers();
@@ -540,8 +538,6 @@ FCIMPL0(INT32, ExceptionNative::GetExceptionCode)
     INT32 retVal = 0;
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
     if (pThread->IsExceptionInProgress())
     {
         retVal = pThread->GetExceptionState()->GetExceptionCode();
index 6d0f9f7..c59d8ad 100644 (file)
@@ -63,7 +63,6 @@ UINT32 TypeIDMap::LookupTypeID(PTR_MethodTable pMT)
 {
     CONTRACTL {
         NOTHROW;
-        PRECONDITION(CheckPointer(GetThread()));
         if (GetThread()->PreemptiveGCDisabled()) { GC_NOTRIGGER; } else { GC_TRIGGERS; }
     } CONTRACTL_END;
 
@@ -79,7 +78,6 @@ PTR_MethodTable TypeIDMap::LookupType(UINT32 id)
 {
     CONTRACTL {
         NOTHROW;
-        PRECONDITION(CheckPointer(GetThread()));
         if (GetThread()->PreemptiveGCDisabled()) { GC_NOTRIGGER; } else { GC_TRIGGERS; }
         PRECONDITION(id <= TypeIDProvider::MAX_TYPE_ID);
     } CONTRACTL_END;
index 920502d..689cf04 100644 (file)
@@ -129,7 +129,7 @@ HRESULT CorHost2::Stop()
     {
         NOTHROW;
         ENTRY_POINT;    // We're bringing the EE down, so no point in probing
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
     if (!g_fEEStarted)
@@ -210,7 +210,7 @@ HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId)
     }
     else
     {
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (!pThread)
         {
             hr = E_UNEXPECTED;
@@ -332,7 +332,7 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
 
     AppDomain *pCurDomain = SystemDomain::GetCurrentDomain();
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         pThread = SetupThreadNoThrow(&hr);
@@ -425,7 +425,7 @@ HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath,
 
     BEGIN_ENTRYPOINT_NOTHROW;
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         pThread = SetupThreadNoThrow(&hr);
@@ -528,7 +528,7 @@ HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId,
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -566,7 +566,7 @@ HRESULT CorHost2::CreateAppDomainWithManager(
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -712,7 +712,7 @@ HRESULT CorHost2::CreateDelegate(
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -800,7 +800,7 @@ HRESULT CorHost2::Authenticate(ULONGLONG authKey)
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -814,7 +814,7 @@ HRESULT CorHost2::RegisterMacEHPort()
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -827,7 +827,7 @@ HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag)
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         ENTRY_POINT;  // This is called by a host.
     }
     CONTRACTL_END;
@@ -1071,7 +1071,7 @@ HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl)
 // Note: Sampling profilers also use this function to initialize TLS for a unmanaged
 // sampling thread so that initialization can be done in advance to avoid deadlocks.
 // See ProfToEEInterfaceImpl::InitializeCurrentThread for more details.
-void SetupTLSForThread(Thread* pThread)
+void SetupTLSForThread()
 {
     STATIC_CONTRACT_THROWS;
     STATIC_CONTRACT_GC_NOTRIGGER;
index cbfb665..63472e4 100644 (file)
@@ -288,15 +288,13 @@ void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CH
     Thread * pThread;
     BOOL fToggle;
 
-    BEGIN_GETTHREAD_ALLOWED;
-    pThread = GetThread();
+    pThread = GetThreadNULLOk();
     fToggle = ((m_dwFlags & (CRST_UNSAFE_ANYMODE | CRST_UNSAFE_COOPGC | CRST_GC_NOTRIGGER_WHEN_TAKEN)) == 0)   // condition normally false
               && pThread &&  pThread->PreemptiveGCDisabled();
 
     if (fToggle) {
         pThread->EnablePreemptiveGC();
     }
-    END_GETTHREAD_ALLOWED;
 
 #ifdef _DEBUG
     PreEnter ();
@@ -329,9 +327,9 @@ void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CH
 
     if (fToggle)
     {
-        BEGIN_GETTHREAD_ALLOWED;
+        
         pThread->DisablePreemptiveGC();
-        END_GETTHREAD_ALLOWED;
+        
     }
 }
 
@@ -351,7 +349,7 @@ void CrstBase::Leave()
 #endif //_DEBUG
 
 #if defined(_DEBUG)
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 #endif
 
     LeaveCriticalSection(&m_criticalsection);
@@ -703,14 +701,14 @@ BOOL CrstBase::IsSafeToTake()
     // If there is no thread object, we ignore the check since this thread isn't
     // coordinated with the GC.
     Thread * pThread;
-    BEGIN_GETTHREAD_ALLOWED;
-    pThread = GetThread();
+    
+    pThread = GetThreadNULLOk();
 
     _ASSERTE(pThread == NULL ||
              (pThread->PreemptiveGCDisabled() == ((m_dwFlags & CRST_UNSAFE_COOPGC) != 0)) ||
              ((m_dwFlags & (CRST_UNSAFE_ANYMODE | CRST_GC_NOTRIGGER_WHEN_TAKEN)) != 0) ||
              (GCHeapUtilities::IsGCInProgress() && pThread == ThreadSuspend::GetSuspensionThread()));
-    END_GETTHREAD_ALLOWED;
+    
 
     if (m_holderthreadid.IsCurrentThread())
     {
@@ -792,7 +790,6 @@ CrstBase::CrstAndForbidSuspendForDebuggerHolder::CrstAndForbidSuspendForDebugger
     _ASSERTE((pCrst->m_dwFlags & CRST_REENTRANCY) == 0);
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread != nullptr);
     if (pThread->IsInForbidSuspendForDebuggerRegion())
     {
         AcquireLock(pCrst);
index 708b4ff..939fe94 100644 (file)
@@ -392,7 +392,6 @@ public:
 
     virtual BOOL ShouldAutoAttach() = 0;
     virtual BOOL FallbackJITAttachPrompt() = 0;
-    virtual HRESULT SetFiberMode(bool isFiberMode) = 0;
 
 #ifdef FEATURE_INTEROP_DEBUGGING
     virtual LONG FirstChanceSuspendHijackWorker(PCONTEXT pContext, PEXCEPTION_RECORD pExceptionRecord) = 0;
index 5027ebf..a7c3c8e 100644 (file)
@@ -66,8 +66,6 @@ UINT_PTR FindMostRecentUserCodeOnStack(void)
     CONTRACTL_END;
 
     Thread * pThread = GetThread();
-    _ASSERTE(pThread != NULL);
-
     UINT_PTR address = NULL;
 
     CONTEXT ctx;
index 87c30a7..d4868c3 100644 (file)
@@ -700,18 +700,6 @@ PCCOR_SIGNATURE RawSigForMethodDesc(MethodDesc* pMD)
     return(pMD->GetSig());
 }
 
-Thread * CurrentThreadInfo ()
-{
-    CONTRACTL
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-    }
-    CONTRACTL_END;
-
-    return GetThread ();
-}
-
 SyncBlock *GetSyncBlockForObject(UINT_PTR obj)
 {
     CONTRACTL
index 4736bd4..3791460 100644 (file)
@@ -531,10 +531,10 @@ void STDCALL LogUMTransition(UMEntryThunk* thunk)
         DEBUG_ONLY;
         GC_NOTRIGGER;
         ENTRY_POINT;
-        if (GetThread()) MODE_PREEMPTIVE; else MODE_ANY;
+        if (GetThreadNULLOk()) MODE_PREEMPTIVE; else MODE_ANY;
         DEBUG_ONLY;
         PRECONDITION(CheckPointer(thunk));
-        PRECONDITION((GetThread() != NULL) ? (!GetThread()->PreemptiveGCDisabled()) : TRUE);
+        PRECONDITION((GetThreadNULLOk() != NULL) ? (!GetThread()->PreemptiveGCDisabled()) : TRUE);
     }
     CONTRACTL_END;
 
index 8176715..7eaa37e 100644 (file)
@@ -465,10 +465,7 @@ BOOL DomainFile::DoIncrementalLoad(FileLoadLevel level)
     if (IsError())
         return FALSE;
 
-    Thread *pThread;
-    pThread = GetThread();
-    _ASSERTE(pThread);
-
+    Thread *pThread = GetThread();
     switch (level)
     {
     case FILE_LOAD_BEGIN:
index 0370edd..e42fbf7 100644 (file)
@@ -855,7 +855,7 @@ HRESULT GetBucketParametersForCurrentException(
     GenericModeBlock gmb;
 
     // Make sure this is (or at least has been) a managed thread.
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {   // Not the greatest error, but we don't expect to be called on a unmanaged thread.
         return E_UNEXPECTED;
index 5069546..c0b6830 100644 (file)
@@ -32,8 +32,7 @@ void EEContract::DoChecks(UINT testmask, __in_z const char *szFunction, __in_z c
     // Many of the checks below result in calls to GetThread()
     // that work just fine if GetThread() returns NULL, so temporarily
     // allow such calls.
-    BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-    m_pThread = GetThread();
+    m_pThread = GetThreadNULLOk();
     m_pClrDebugState = GetClrDebugState();
 
     // Call our base DoChecks.
@@ -199,56 +198,5 @@ void EEContract::DoChecks(UINT testmask, __in_z const char *szFunction, __in_z c
         default:
             UNREACHABLE();
     }
-    END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-
-    // EE Thread-required check
-    // NOTE: The following must NOT be inside BEGIN/END_GETTHREAD_ALLOWED,
-    // as the change to m_pClrDebugState->m_allowGetThread below would be
-    // overwritten by END_GETTHREAD_ALLOWED.
-    switch (testmask & EE_THREAD_Mask)
-    {
-        case EE_THREAD_Required:
-            if (!((EEThreadViolation|BadDebugState) & m_pClrDebugState->ViolationMask()))
-            {
-                if (m_pThread == NULL)
-                {
-                    CONTRACT_ASSERT("EE_THREAD_REQUIRED encountered with no current EE Thread object in TLS.",
-                                    Contract::EE_THREAD_Required,
-                                    Contract::EE_THREAD_Mask,
-                                    m_contractStackRecord.m_szFunction,
-                                    m_contractStackRecord.m_szFile,
-                                    m_contractStackRecord.m_lineNum
-                                   );
-                }
-                else if (!m_pClrDebugState->IsGetThreadAllowed())
-                {
-                    // In general, it's unsafe for an EE_THREAD_NOT_REQUIRED function to
-                    // call an EE_THREAD_REQUIRED function. In cases where it is safe,
-                    // you may wrap the call to the EE_THREAD_REQUIRED function inside a
-                    // BEGIN/END_GETTHREAD_ALLOWED block, but you may only do so if the
-                    // case where GetThread() == NULL is clearly handled in a way that
-                    // prevents entry into the BEGIN/END_GETTHREAD_ALLOWED block.
-                    CONTRACT_ASSERT("EE_THREAD_REQUIRED encountered in an EE_THREAD_NOT_REQUIRED scope, without an intervening BEGIN/END_GETTHREAD_ALLOWED block.",
-                                    Contract::EE_THREAD_Required,
-                                    Contract::EE_THREAD_Mask,
-                                    m_contractStackRecord.m_szFunction,
-                                    m_contractStackRecord.m_szFile,
-                                    m_contractStackRecord.m_lineNum
-                                   );
-                }
-            }
-            m_pClrDebugState->SetGetThreadAllowed();
-            break;
-
-        case EE_THREAD_Not_Required:
-            m_pClrDebugState->ResetGetThreadAllowed();
-            break;
-
-        case EE_THREAD_Disabled:
-            break;
-
-        default:
-            UNREACHABLE();
-    }
 }
 #endif // ENABLE_CONTRACTS
index 1c2776a..61adea1 100644 (file)
@@ -52,16 +52,6 @@ class EEContract : public BaseContract
 #define GC_TRIGGERS          do { STATIC_CONTRACT_GC_TRIGGERS; REQUEST_TEST(Contract::GC_Triggers,   Contract::GC_Disabled); } while(0)
 #define GC_NOTRIGGER         do { STATIC_CONTRACT_GC_NOTRIGGER; REQUEST_TEST(Contract::GC_NoTrigger,  Contract::GC_Disabled); } while(0)
 
-// Notice there's no static contract component to this.  It's
-// perfectly reasonable to find EE_THREAD_REQUIRED inside the scope of
-// EE_THREAD_NOT_REQUIRED (e.g., an EE_THREAD_NOT_REQUIRED scope can have two
-// possible code paths--one with an EE Thread and one without).  So we can't do
-// any meaningful testing statically.  It's all gotta be done at runtime.
-#define EE_THREAD_NOT_REQUIRED  \
-                             do { REQUEST_TEST(Contract::EE_THREAD_Not_Required, Contract::EE_THREAD_Disabled); } while(0)
-
-#define EE_THREAD_REQUIRED   do { REQUEST_TEST(Contract::EE_THREAD_Required, Contract::EE_THREAD_Disabled); } while(0)
-
 #define HOST_NOCALLS         do { STATIC_CONTRACT_HOST_NOCALLS; REQUEST_TEST(Contract::HOST_NoCalls, Contract::HOST_Disabled); } while(0)
 #define HOST_CALLS           do {  STATIC_CONTRACT_HOST_CALLS; REQUEST_TEST(Contract::HOST_Calls, Contract::HOST_Disabled); } while(0)
 
@@ -74,12 +64,11 @@ class EEContract : public BaseContract
 #define GC_NOTRIGGER
 #define HOST_NOCALLS
 #define HOST_CALLS
-#define EE_THREAD_NOT_REQUIRED
-#define EE_THREAD_REQUIRED
-
 
 #endif  // ENABLE_CONTRACTS_IMPL
 
+#define EE_THREAD_NOT_REQUIRED
+
 // Replace the CONTRACT macro with the EE version
 #undef CONTRACT
 #define CONTRACT(_returntype)  CUSTOM_CONTRACT(EEContract, _returntype)
index 002250d..ba48f89 100644 (file)
@@ -54,7 +54,7 @@ Thread* EEDbgInterfaceImpl::GetThread(void)
     CONTRACT_END;
 #endif
 
-    return ::GetThread();
+    return ::GetThreadNULLOk();
 }
 
 #ifndef DACCESS_COMPILE
index cfc23bf..108bf87 100644 (file)
@@ -677,10 +677,8 @@ BOOL EEHashTableBase<KeyType, Helper, bDefaultCopyIsDeep>::GrowHashTable()
     CONTRACTL_END
 
 #if defined(_DEBUG) && !defined(CROSSGEN_COMPILE)
-    BEGIN_GETTHREAD_ALLOWED;
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
     _ASSERTE(!g_fEEStarted || (pThread == NULL) || (pThread->PreemptiveGCDisabled()));
-    END_GETTHREAD_ALLOWED;
 #endif
 
     // Make the new bucket table 4 times bigger
index 8607432..8abaf6f 100644 (file)
@@ -133,8 +133,7 @@ void EEPolicy::HandleStackOverflow()
 
     STRESS_LOG0(LF_EH, LL_INFO100, "In EEPolicy::HandleStackOverflow\n");
 
-    Thread *pThread = GetThread();
-
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         // For security reason, it is not safe to continue execution if stack overflow happens
@@ -353,7 +352,7 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, LPCWSTR errorSource
 
     static Thread *volatile s_pCrashingThread = FatalErrorNotSeenYet;
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     Thread *pPreviousThread = InterlockedCompareExchangeT<Thread *>(&s_pCrashingThread, pThread, FatalErrorNotSeenYet);
 
     if (pPreviousThread == pThread)
@@ -541,7 +540,7 @@ void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage
     {
 #ifdef DEBUGGING_SUPPORTED
         //Give a managed debugger a chance if this fatal error is on a managed thread.
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
 
         if (pThread && !g_fFatalErrorOccuredOnGCThread)
         {
@@ -639,7 +638,7 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE
     {
         DisplayStackOverflowException();
 
-        HandleHolder stackDumpThreadHandle = Thread::CreateUtilityThread(Thread::StackSize_Small, LogStackOverflowStackTraceThread, GetThread(), W(".NET Stack overflow trace logger"));
+        HandleHolder stackDumpThreadHandle = Thread::CreateUtilityThread(Thread::StackSize_Small, LogStackOverflowStackTraceThread, GetThreadNULLOk(), W(".NET Stack overflow trace logger"));
         if (stackDumpThreadHandle != INVALID_HANDLE_VALUE)
         {
             // Wait for the stack trace logging completion
@@ -670,7 +669,7 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE
 
     if (!fSkipDebugger)
     {
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         BOOL fTreatAsNativeUnhandledException = FALSE;
         if (pThread)
         {
@@ -789,7 +788,7 @@ int NOINLINE EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR
         // because debugger is going to take CrstDebuggerMutex, whose lock level is higher than that of
         // CrstThreadStore.  It should be safe to release the lock since execution will not be resumed
         // after fatal errors.
-        if (ThreadStore::HoldingThreadStore(GetThread()))
+        if (ThreadStore::HoldingThreadStore(GetThreadNULLOk()))
         {
             ThreadSuspend::UnlockThreadStore();
         }
index 22708c8..34cd147 100644 (file)
 //      CLR_TO_PROFILER_ENTRYPOINT (typical choice)
 //          This is used for calling ICorProfilerCallback* methods that either have no
 //          ThreadID parameters, or if they do have a ThreadID parameter, the parameter's
-//          value is always the *current* ThreadID (i.e., param == GetThread()).  This will
+//          value is always the *current* ThreadID (i.e., param == GetThreadNULLOk()).  This will
 //          also force a mode switch to preemptive before calling the profiler.
 //      CLR_TO_PROFILER_ENTRYPOINT_FOR_THREAD
 //          Similar to above, except these are used for ICorProfilerCallback* methods that
 //          specify a ThreadID parameter whose value may not always be the *current*
 //          ThreadID.  You must specify the ThreadID as the first parameter to these
 //          macros.  The macro will then use your ThreadID rather than that of the current
-//          GetThread(), to assert that the callback is currently allowed for that
+//          GetThreadNULLOk(), to assert that the callback is currently allowed for that
 //          ThreadID (i.e., that we have not yet issued a ThreadDestroyed() for that
 //          ThreadID).
 //
@@ -4468,7 +4468,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionThrown(
                                 LL_INFO1000,
                                 "**PROF: ExceptionThrown. ObjectID: 0x%p. ThreadID: 0x%p\n",
                                 thrownObjectId,
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4504,7 +4504,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionSearchFunctionEnter(
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionSearchFunctionEnter. ThreadID: 0x%p, functionId: 0x%p\n",
-                                GetThread(),
+                                GetThreadNULLOk(),
                                 functionId));
 
     {
@@ -4540,7 +4540,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionSearchFunctionLeave()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionSearchFunctionLeave. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4575,7 +4575,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionSearchFilterEnter(FunctionID functionId)
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionSearchFilterEnter. ThreadID: 0x%p, functionId: 0x%p\n",
-                                GetThread(),
+                                GetThreadNULLOk(),
                                 functionId));
 
     {
@@ -4611,7 +4611,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionSearchFilterLeave()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionFilterLeave. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4646,7 +4646,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionSearchCatcherFound(FunctionID functionId
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionSearchCatcherFound.  ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4696,7 +4696,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionUnwindFunctionEnter(FunctionID functionI
         (LF_CORPROF,
         LL_INFO1000,
         "**PROF: ExceptionUnwindFunctionEnter. ThreadID: 0x%p, functionId: 0x%p\n",
-        GetThread(),
+        GetThreadNULLOk(),
         functionId));
 
     {
@@ -4735,7 +4735,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionUnwindFunctionLeave()
         (LF_CORPROF,
         LL_INFO1000,
         "**PROF: ExceptionUnwindFunctionLeave. ThreadID: 0x%p\n",
-        GetThread()));
+        GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4773,7 +4773,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionUnwindFinallyEnter(FunctionID functionId
         (LF_CORPROF,
         LL_INFO1000,
         "**PROF: ExceptionUnwindFinallyEnter. ThreadID: 0x%p, functionId: 0x%p\n",
-        GetThread(),
+        GetThreadNULLOk(),
         functionId));
 
     {
@@ -4812,7 +4812,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionUnwindFinallyLeave()
         (LF_CORPROF,
         LL_INFO1000,
         "**PROF: ExceptionUnwindFinallyLeave. ThreadID: 0x%p\n",
-        GetThread()));
+        GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -4849,7 +4849,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionCatcherEnter(FunctionID functionId, Obje
         kEE2PNoTrigger,
         (LF_CORPROF,
         LL_INFO1000, "**PROF: ExceptionCatcherEnter.        ThreadID: 0x%p, functionId: 0x%p\n",
-        GetThread(),
+        GetThreadNULLOk(),
         functionId));
 
     {
@@ -4886,7 +4886,7 @@ HRESULT EEToProfInterfaceImpl::ExceptionCatcherLeave()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: ExceptionCatcherLeave.        ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
 
     {
@@ -5023,7 +5023,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeSuspendStarted(
         (LF_CORPROF,
         LL_INFO100,
         "**PROF: RuntimeSuspendStarted. ThreadID 0x%p.\n",
-        GetThread()));
+        GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5061,7 +5061,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeSuspendFinished()
         (LF_CORPROF,
         LL_INFO100,
         "**PROF: RuntimeSuspendFinished. ThreadID 0x%p.\n",
-        GetThread()));
+        GetThreadNULLOk()));
 
 
     {
@@ -5105,7 +5105,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeSuspendAborted()
         (LF_CORPROF,
         LL_INFO100,
         "**PROF: RuntimeSuspendAborted. ThreadID 0x%p.\n",
-        GetThread()));
+        GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5141,7 +5141,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeResumeStarted()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO100,
                                 "**PROF: RuntimeResumeStarted. ThreadID 0x%p.\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5175,7 +5175,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeResumeFinished()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO100,
                                 "**PROF: RuntimeResumeFinished. ThreadID 0x%p.\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5266,7 +5266,7 @@ HRESULT EEToProfInterfaceImpl::RuntimeThreadSuspended(ThreadID suspendedThreadId
         // (4) from occurring until 3) is completely done.  It's sufficient to determine we're in 3) by noting
         // whether the callback is reporting that a thread is "suspending itself" (i.e., suspendedThreadId == threadId)
 
-        ForbidSuspendThreadHolder forbidSuspendThread((Thread *) suspendedThreadId == GetThread());
+        ForbidSuspendThreadHolder forbidSuspendThread((Thread *) suspendedThreadId == GetThreadNULLOk());
 
         {
             // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5367,7 +5367,7 @@ HRESULT EEToProfInterfaceImpl::RemotingClientInvocationStarted()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingClientInvocationStarted. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5402,7 +5402,7 @@ HRESULT EEToProfInterfaceImpl::RemotingClientSendingMessage(GUID *pCookie, BOOL
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingClientSendingMessage. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5437,7 +5437,7 @@ HRESULT EEToProfInterfaceImpl::RemotingClientReceivingReply(GUID * pCookie, BOOL
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingClientReceivingReply. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5472,7 +5472,7 @@ HRESULT EEToProfInterfaceImpl::RemotingClientInvocationFinished()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingClientInvocationFinished. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5507,7 +5507,7 @@ HRESULT EEToProfInterfaceImpl::RemotingServerReceivingMessage(GUID *pCookie, BOO
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingServerReceivingMessage. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5542,7 +5542,7 @@ HRESULT EEToProfInterfaceImpl::RemotingServerInvocationStarted()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingServerInvocationStarted. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5577,7 +5577,7 @@ HRESULT EEToProfInterfaceImpl::RemotingServerInvocationReturned()
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingServerInvocationReturned. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5612,7 +5612,7 @@ HRESULT EEToProfInterfaceImpl::RemotingServerSendingReply(GUID *pCookie, BOOL fI
     CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
                                 LL_INFO1000,
                                 "**PROF: RemotingServerSendingReply. ThreadID: 0x%p\n",
-                                GetThread()));
+                                GetThreadNULLOk()));
 
     {
         // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
index 24252f3..1e907d0 100644 (file)
@@ -532,7 +532,6 @@ PCODE EditAndContinueModule::JitUpdatedFunction( MethodDesc *pMD,
     // so that gc can crawl the stack and do the right thing.
     _ASSERTE(pOrigContext);
     Thread *pCurThread = GetThread();
-    _ASSERTE(pCurThread);
     FrameWithCookie<ResumableFrame> resFrame(pOrigContext);
     resFrame.Push(pCurThread);
 
@@ -801,8 +800,6 @@ NOINLINE void EditAndContinueModule::FixContextAndResume(
     LOG((LF_ENC, LL_INFO100, "EnCModule::ResumeInUpdatedFunction: Resume at EIP=0x%x\n", pNewCodeInfo->GetCodeAddress()));
 
     Thread *pCurThread = GetThread();
-    _ASSERTE(pCurThread);
-
     pCurThread->SetFilterContext(pContext);
     SetIP(pContext, pNewCodeInfo->GetCodeAddress());
 
index 36ff9eb..c7edf06 100644 (file)
@@ -2767,7 +2767,7 @@ ep_rt_thread_handle_t
 ep_rt_thread_get_handle (void)
 {
        STATIC_CONTRACT_NOTHROW;
-       return GetThread ();
+       return GetThreadNULLOk ();
 }
 
 static
index 8bcc00e..7d0e429 100644 (file)
@@ -162,7 +162,7 @@ int QCALLTYPE EventPipeInternal::EventActivityIdControl(uint32_t controlCode, GU
 
     BEGIN_QCALL;
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL || pActivityId == NULL)
     {
         retVal = 1;
index f8e3ef7..318cc21 100644 (file)
@@ -547,8 +547,6 @@ StackWalkAction LogCallstackForEventReporterCallback(
 void LogCallstackForEventReporterWorker(EventReporter& reporter)
 {
     Thread* pThread = GetThread();
-    _ASSERTE (pThread);
-
     SmallStackSString WordAt;
 
     if (!WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT))
@@ -670,7 +668,7 @@ void DoReportForUnhandledNativeException(PEXCEPTION_POINTERS pExceptionInfo)
 
     if (ShouldLogInEventLog())
     {
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         EventReporter reporter(EventReporter::ERT_UnhandledException);
         EX_TRY
         {
index 0f014ab..99620ac 100644 (file)
@@ -321,7 +321,7 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
         return ETW::SamplingLog::UnInitialized;
     }
 #endif // TARGET_AMD64
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         return ETW::SamplingLog::UnInitialized;
@@ -3340,7 +3340,7 @@ BOOL ETW::TypeSystemLog::ShouldLogType(TypeHandle th)
 
     // When we have a thread context, default to calling the API that requires one which
     // reduces the cost of locking.
-    if (GetThread() != NULL)
+    if (GetThreadNULLOk() != NULL)
     {
         LookupOrCreateTypeLoggingInfo(th, &fCreatedNew);
     }
@@ -4701,7 +4701,7 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame  *pCf, BOOL bIsReThrownExcept
     CONTRACTL {
         NOTHROW;
         GC_TRIGGERS;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(GetThread()->GetThrowable() != NULL);
     } CONTRACTL_END;
 
index 34afa5b..1b192e6 100644 (file)
@@ -551,10 +551,10 @@ void CreateTypeInitializationExceptionObject(LPCWSTR pTypeThatFailed,
         PRECONDITION(IsProtectedByGCFrame(pInnerException));
         PRECONDITION(IsProtectedByGCFrame(pInitException));
         PRECONDITION(IsProtectedByGCFrame(pThrowable));
-        PRECONDITION(CheckPointer(GetThread()));
+        PRECONDITION(CheckPointer(GetThreadNULLOk()));
     } CONTRACTL_END;
 
-    Thread *pThread  = GetThread();
+    Thread *pThread  = GetThreadNULLOk();
     *pThrowable = NULL;
 
     // This will make sure to put the thread back to its original state if something
@@ -2974,7 +2974,7 @@ void FreeExceptionData(ExceptionData *pedata)
     // <TODO>@NICE: At one point, we had the comment:
     //     (DM) Remove this when shutdown works better.</TODO>
     // This test may no longer be necessary.  Remove at own peril.
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (!pThread)
         return;
 
@@ -3384,7 +3384,6 @@ BOOL StackTraceInfo::AppendElement(BOOL bAllowAllocMem, UINT_PTR currentIP, UINT
 
 #ifndef TARGET_UNIX // Watson is supported on Windows only
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
 
     if (pThread && (currentIP != 0))
     {
@@ -3499,7 +3498,7 @@ BOOL IsAsyncThreadException(OBJECTREF *pThrowable) {
     STATIC_CONTRACT_MODE_COOPERATIVE;
     STATIC_CONTRACT_FORBID_FAULT;
 
-    if (  (GetThread() && GetThread()->IsRudeAbort() && GetThread()->IsRudeAbortInitiated())
+    if (  (GetThreadNULLOk() && GetThread()->IsRudeAbort() && GetThread()->IsRudeAbortInitiated())
         ||IsExceptionOfType(kThreadAbortException, pThrowable)
         ||IsExceptionOfType(kThreadInterruptedException, pThrowable)) {
         return TRUE;
@@ -3519,7 +3518,7 @@ BOOL IsUncatchable(OBJECTREF *pThrowable)
 
     _ASSERTE(pThrowable != NULL);
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     if (pThread)
     {
@@ -3982,7 +3981,7 @@ LONG WatsonLastChance(                  // EXCEPTION_CONTINUE_SEARCH, _CONTINUE_
             }
             else
             {
-                g_pDebugInterface->LaunchDebuggerForUser(GetThread(), pExceptionInfo, FALSE, FALSE);
+                g_pDebugInterface->LaunchDebuggerForUser(GetThreadNULLOk(), pExceptionInfo, FALSE, FALSE);
             }
 
             return EXCEPTION_CONTINUE_SEARCH;
@@ -4203,8 +4202,7 @@ bool CheckThreadExceptionStateForInterception()
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread* pThread = GetThread();
-
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         return false;
@@ -4249,7 +4247,7 @@ BOOL ExceptionIsAlwaysSwallowed(EXCEPTION_POINTERS *pExceptionInfo)
     if (IsComPlusException(pExceptionInfo->ExceptionRecord))
     {
         // Our exception code.  Get the current exception from the thread.
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (pThread)
         {
             OBJECTREF throwable;
@@ -4614,7 +4612,7 @@ LONG InternalUnhandledExceptionFilter_Worker(
     }
 
     // We don't do anything when this is called from an unmanaged thread.
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
 #ifdef _DEBUG
     static bool bBreakOnUncaught = false;
@@ -4881,7 +4879,7 @@ lDone: ;
 #ifdef _DEBUG
         char buffer[200];
         sprintf_s(buffer, 200, "\nInternal error: Uncaught exception was thrown from IP = %p in UnhandledExceptionFilter_Worker on thread 0x%08x\n",
-                param.ExceptionEIP, ((GetThread() == NULL) ? NULL : GetThread()->GetThreadId()));
+                param.ExceptionEIP, ((GetThreadNULLOk() == NULL) ? NULL : GetThread()->GetThreadId()));
         PrintToStdErrA(buffer);
         _ASSERTE(!"Unexpected exception in UnhandledExceptionFilter_Worker");
 #endif
@@ -5046,8 +5044,8 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData)
         return EXCEPTION_CONTINUE_SEARCH;
     }
 
-    Thread* pThread = GetThread();
-    if (pThread && !GetThread()->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException))
+    Thread* pThread = GetThreadNULLOk();
+    if (pThread && !pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException))
     {
         // Invoke the UEF worker to perform unhandled exception processing
         ret = InternalUnhandledExceptionFilter_Worker (pExceptionInfo);
@@ -5105,7 +5103,7 @@ LONG __stdcall COMUnhandledExceptionFilter(     // EXCEPTION_CONTINUE_SEARCH or
     // various runtimes again.
     //
     // Thus, check if this UEF has already been invoked in context of this thread and runtime and if so, dont invoke it again.
-    if (GetThread() && (GetThread()->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException)))
+    if (GetThreadNULLOk() && (GetThread()->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException)))
     {
         LOG((LF_EH, LL_INFO10, "Exiting COMUnhandledExceptionFilter since we have already done UE processing for this thread!\n"));
         return retVal;
@@ -5115,7 +5113,7 @@ LONG __stdcall COMUnhandledExceptionFilter(     // EXCEPTION_CONTINUE_SEARCH or
     retVal = InternalUnhandledExceptionFilter(pExceptionInfo);
 
     // If thread object exists, mark that this thread has done unhandled exception processing
-    if (GetThread())
+    if (GetThreadNULLOk())
     {
         LOG((LF_EH, LL_INFO100, "COMUnhandledExceptionFilter: setting TSNC_ProcessedUnhandledException\n"));
         GetThread()->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException);
@@ -5257,7 +5255,7 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers,
     int suppressSelectiveBreak = false; // to filter for the case where breakOnUncaught == "2"
 #endif
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     //     The following reduces a window for a race during shutdown.
     if (!pThread)
@@ -5444,7 +5442,7 @@ BOOL NotifyAppDomainsOfUnhandledException(
 
     LOG((LF_EH, LL_INFO10, "In NotifyAppDomainsOfUnhandledException\n"));
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     //     The following reduces a window for a race during shutdown.
     if (!pThread)
@@ -5596,7 +5594,6 @@ static LONG ThreadBaseExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo,
     _ASSERTE(!g_fNoExceptions);
 
     Thread* pThread = GetThread();
-    _ASSERTE(pThread);
 
 #ifdef _DEBUG
     if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnUncaughtException) &&
@@ -6313,7 +6310,7 @@ CreateCOMPlusExceptionObject(Thread *pThread, EXCEPTION_RECORD *pExceptionRecord
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() == pThread);
+    _ASSERTE(GetThreadNULLOk() == pThread);
 
     DWORD exceptionCode = pExceptionRecord->ExceptionCode;
 
@@ -6477,7 +6474,7 @@ bool IsGcMarker(CONTEXT* pContext, EXCEPTION_RECORD *pExceptionRecord)
         //
         // Note these "fake" AVs will be reported by the kernel as reads from
         // address 0xF...F so we also use that as a screen.
-        Thread* pThread = GetThread();
+        Thread* pThread = GetThreadNULLOk();
         if (exceptionCode == STATUS_ACCESS_VIOLATION &&
             GCStress<cfg_instr>::IsEnabled() &&
             pExceptionRecord->ExceptionInformation[0] == 0 &&
@@ -6571,7 +6568,7 @@ IsDebuggerFault(EXCEPTION_RECORD *pExceptionRecord,
     // Even if a debugger is not attached, we must let the debugger handle the exception in case it's coming from a
     // patch-skipper.
     if ((!IsComPlusException(pExceptionRecord)) &&
-        (GetThread() != NULL) &&
+        (GetThreadNULLOk() != NULL) &&
         (g_pDebugInterface != NULL) &&
         g_pDebugInterface->FirstChanceNativeException(pExceptionRecord,
                                                       pContext,
@@ -6612,7 +6609,7 @@ BOOL IsIPinVirtualStub(PCODE f_IP)
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     // We may not have a managed thread object. Example is an AV on the helper thread.
     // (perhaps during StubManager::IsStub)
@@ -7138,7 +7135,7 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
     {
         MAYBE_FAULT_FORBID_NO_ALLOC((pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_NO_MEMORY));
 
-        pThread = GetThread();
+        pThread = GetThreadNULLOk();
 
         //
         // Since we are in an OOM situation, we test the thread object before logging since if the
@@ -7279,7 +7276,7 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo
         //
         // @TODO: I'd love a way to call into the debugger with GCX_NOTRIGGER still in scope, and force them to make
         // the choice to break the no-trigger region after taking all necessary precautions.
-        if (IsDebuggerFault(pExceptionRecord, pExceptionInfo->ContextRecord, pExceptionRecord->ExceptionCode, GetThread()))
+        if (IsDebuggerFault(pExceptionRecord, pExceptionInfo->ContextRecord, pExceptionRecord->ExceptionCode, GetThreadNULLOk()))
         {
             return EXCEPTION_CONTINUE_EXECUTION;
         }
@@ -7460,7 +7457,7 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
             // time, then skip the check for whether or not the AV is in our impl.
             // AVs are ok on the Helper thread (for which there is no pThread object,
             // and so the AVInRuntime holder doesn't work.
-            Thread *pThread = GetThread();
+            Thread *pThread = GetThreadNULLOk();
 
             bool fAVisOk =
                 (IsDbgHelperSpecialThread() || IsETWRundownSpecialThread() ||
@@ -7893,7 +7890,7 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
     // exceptions on this thread.  Indeed, even checking to see if the faulting
     // address is in JITted code is problematic if we have no Thread object, since
     // this thread will bypass all our locks.
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     if (pThread)
     {
@@ -8256,7 +8253,7 @@ LONG NotifyOfCHFFilterWrapper(
     // 1) The thread object has been set up.
     // 2) The thread has an exception on it.
     // 3) The exception is the same as the one this filter is called on.
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if ( (pThread == NULL)  ||
          (pThread->GetExceptionState()->GetContextRecord() == NULL)  ||
          (GetSP(pThread->GetExceptionState()->GetContextRecord()) != GetSP(pExceptionInfo->ContextRecord) ) )
@@ -8665,8 +8662,6 @@ void SetReversePInvokeEscapingUnhandledExceptionStatus(BOOL fIsUnwinding,
     LIMITED_METHOD_CONTRACT;
 
     Thread *pCurThread = GetThread();
-    _ASSERTE(pCurThread);
-
     if (pCurThread->GetExceptionState()->IsExceptionInProgress())
     {
         if (!fIsUnwinding)
@@ -8732,7 +8727,7 @@ BOOL SetupWatsonBucketsForNonPreallocatedExceptions(OBJECTREF oThrowable /* = NU
         GC_TRIGGERS;
         MODE_COOPERATIVE;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
     }
     CONTRACTL_END;
 
@@ -8849,7 +8844,7 @@ BOOL SetupWatsonBucketsForEscapingPreallocatedExceptions()
         GC_TRIGGERS;
         MODE_ANY;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
     }
     CONTRACTL_END;
 
@@ -8978,7 +8973,7 @@ void SetupWatsonBucketsForUEF(BOOL fUseLastThrownObject)
         GC_TRIGGERS;
         MODE_ANY;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
     }
     CONTRACTL_END;
 
@@ -9157,7 +9152,7 @@ BOOL IsThrowableThreadAbortException(OBJECTREF oThrowable)
         GC_NOTRIGGER;
         MODE_COOPERATIVE;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(oThrowable != NULL);
     }
     CONTRACTL_END;
@@ -9206,7 +9201,7 @@ PTR_ExInfo GetEHTrackerForPreallocatedException(OBJECTREF oPreAllocThrowable,
         GC_NOTRIGGER;
         MODE_COOPERATIVE;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(oPreAllocThrowable != NULL);
         PRECONDITION(CLRException::IsPreallocatedExceptionObject(oPreAllocThrowable));
         PRECONDITION(IsWatsonEnabled());
@@ -9265,7 +9260,7 @@ PTR_EHWatsonBucketTracker GetWatsonBucketTrackerForPreallocatedException(OBJECTR
         GC_TRIGGERS;
         MODE_COOPERATIVE;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(oPreAllocThrowable != NULL);
         PRECONDITION(CLRException::IsPreallocatedExceptionObject(oPreAllocThrowable));
         PRECONDITION(IsWatsonEnabled());
@@ -9368,7 +9363,7 @@ doValidation:
         {
             if (fCaptureBucketsIfNotPresent)
             {
-                pWBTracker->CaptureUnhandledInfoForWatson(TypeOfReportedError::UnhandledException, GetThread(), &gc.oPreAllocThrowable);
+                pWBTracker->CaptureUnhandledInfoForWatson(TypeOfReportedError::UnhandledException, GetThreadNULLOk(), &gc.oPreAllocThrowable);
 
                 // Check if we have the buckets now
                 if (pWBTracker->RetrieveWatsonBuckets() != NULL)
@@ -9429,7 +9424,7 @@ BOOL SetupWatsonBucketsForFailFast(EXCEPTIONREF refException)
         GC_TRIGGERS;
         MODE_ANY;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(refException != NULL);
         PRECONDITION(IsWatsonEnabled());
     }
@@ -9689,7 +9684,7 @@ void SetupInitialThrowBucketDetails(UINT_PTR adjustedIp)
         GC_TRIGGERS;
         MODE_ANY;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(!(GetThread()->GetExceptionState()->GetFlags()->GotWatsonBucketDetails()));
         PRECONDITION(adjustedIp != NULL);
         PRECONDITION(IsWatsonEnabled());
@@ -10215,7 +10210,7 @@ BOOL CopyWatsonBucketsToThrowable(PTR_VOID pUnmanagedBuckets, OBJECTREF oTargetT
         GC_TRIGGERS;
         MODE_COOPERATIVE;
         THROWS;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(pUnmanagedBuckets != NULL);
         PRECONDITION(!CLRException::IsPreallocatedExceptionObject((oTargetThrowable == NULL)?GetThread()->GetThrowable():oTargetThrowable));
         PRECONDITION(IsWatsonEnabled());
@@ -10304,7 +10299,7 @@ void SetStateForWatsonBucketing(BOOL fIsRethrownException, OBJECTHANDLE ohOrigin
         GC_TRIGGERS;
         MODE_ANY;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(IsWatsonEnabled());
     }
     CONTRACTL_END;
@@ -10869,7 +10864,7 @@ PTR_ExInfo GetEHTrackerForException(OBJECTREF oThrowable, PTR_ExInfo pStartingEH
         GC_NOTRIGGER;
         MODE_COOPERATIVE;
         NOTHROW;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(oThrowable != NULL);
     }
     CONTRACTL_END;
@@ -11054,7 +11049,7 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN
         THROWS;
         GC_TRIGGERS;
         MODE_COOPERATIVE;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(notificationType  != UnhandledExceptionHandler);
     }
     CONTRACTL_END;
@@ -11124,7 +11119,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa
     }
     CONTRACTL_END;
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     _ASSERTE(pCurThread != NULL);
 
     // Get the current AppDomain
index 478eb2c..4f67a68 100644 (file)
@@ -2045,7 +2045,7 @@ void ExceptionTracker::DebugLogTrackerRanges(__in_z const char *pszTag)
     }
     CONTRACTL_END;
 
-    Thread*             pThread     = GetThread();
+    Thread*             pThread     = GetThreadNULLOk();
     ExceptionTracker*   pTracker    = pThread ? pThread->GetExceptionState()->m_pCurrentTracker : NULL;
 
     int i = 0;
@@ -2430,8 +2430,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
         pMD->m_pszDebugMethodName, pMD->m_pszDebugClassName));
 
     Thread *pThread = GetThread();
-    _ASSERTE (pThread);
-
     INDEBUG( DumpClauses(pcfThisFrame->GetJitManager(), pcfThisFrame->GetMethodToken(), uMethodStartPC, uControlPC) );
 
     bool fIsILStub = pMD->IsILStub();
@@ -3403,7 +3401,7 @@ void ExceptionTracker::PopTrackers(
 
     // Only call into PopTrackers if we have a managed thread and we have an exception progress.
     // Otherwise, the call below (to PopTrackers) is a noop. If this ever changes, then this short-circuit needs to be fixed.
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     if ((pCurThread != NULL) && (pCurThread->GetExceptionState()->IsExceptionInProgress()))
     {
         // Refer to the comment around ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException
@@ -3483,7 +3481,7 @@ void ExceptionTracker::PopTrackers(
     }
     CONTRACTL_END;
 
-    Thread*             pThread     = GetThread();
+    Thread*             pThread     = GetThreadNULLOk();
     ExceptionTracker*   pTracker    = (pThread ? pThread->GetExceptionState()->m_pCurrentTracker : NULL);
 
     // NOTE:
@@ -4027,7 +4025,7 @@ BOOL ExceptionTracker::NotifyDebuggerOfStub(Thread* pThread, StackFrame sf, Fram
 
     if (g_EnableSIS)
     {
-        _ASSERTE(GetThread() == pThread);
+        _ASSERTE(GetThreadNULLOk() == pThread);
 
         GCX_COOP();
 
@@ -4189,7 +4187,7 @@ inline bool ExceptionTracker::IsValid()
 
     EX_TRY
     {
-        Thread* pThisThread = GetThread();
+        Thread* pThisThread = GetThreadNULLOk();
         if (m_pThread == pThisThread)
         {
             fRetVal = true;
@@ -4224,7 +4222,7 @@ BOOL ExceptionTracker::ThrowableIsValid()
 UINT_PTR ExceptionTracker::DebugComputeNestingLevel()
 {
     UINT_PTR uNestingLevel = 0;
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
 
     if (pThread)
     {
@@ -4735,8 +4733,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
     {
         // Get the thread and the thread exception state - they must exist at this point
         Thread *pCurThread = GetThread();
-        _ASSERTE(pCurThread != NULL);
-
         ThreadExceptionState * pCurTES = pCurThread->GetExceptionState();
         _ASSERTE(pCurTES != NULL);
     }
@@ -5074,7 +5070,7 @@ bool IsDivByZeroAnIntegerOverflow(PCONTEXT pContext)
 
 BOOL IsSafeToCallExecutionManager()
 {
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     // It is safe to call the ExecutionManager::IsManagedCode only if the current thread is in
     // the cooperative mode. Otherwise ExecutionManager::IsManagedCode could deadlock if
@@ -5208,7 +5204,7 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
     else
     {
         // This is a breakpoint or single step stop, we report it to the debugger.
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (pThread != NULL && g_pDebugInterface != NULL)
         {
 #if (defined(TARGET_ARM) || defined(TARGET_ARM64))
@@ -5810,7 +5806,7 @@ UMThunkUnwindFrameChainHandler(IN     PEXCEPTION_RECORD   pExceptionRecord
                                IN OUT PDISPATCHER_CONTEXT pDispatcherContext
                               )
 {
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL) {
         return ExceptionContinueSearch;
     }
@@ -5882,7 +5878,7 @@ NOT_BIT64_ARG(IN     ULONG               MemoryStackFp),
     //
     // We check for thread object since this function is the personality routine of the UMThunk
     // and we can landup here even when thread creation (within the thunk) fails.
-    if (GetThread() != NULL)
+    if (GetThreadNULLOk() != NULL)
     {
         SetReversePInvokeEscapingUnhandledExceptionStatus(IS_UNWINDING(pExceptionRecord->ExceptionFlags),
             MemoryStackFp
@@ -5913,8 +5909,6 @@ CallDescrWorkerUnwindFrameChainHandler(IN     PEXCEPTION_RECORD   pExceptionReco
 {
 
     Thread* pThread = GetThread();
-    _ASSERTE(pThread);
-
     if (pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW)
     {
         if (IS_UNWINDING(pExceptionRecord->ExceptionFlags))
index acfa06f..68c0b11 100644 (file)
@@ -43,7 +43,7 @@ void ExInfo::CopyAndClearSource(ExInfo *from)
     {
         NOTHROW;
         GC_NOTRIGGER;
-        if (GetThread() != NULL) MODE_COOPERATIVE; else MODE_ANY;
+        if (GetThreadNULLOk() != NULL) MODE_COOPERATIVE; else MODE_ANY;
         FORBID_FAULT;
     }
     CONTRACTL_END;
@@ -165,7 +165,7 @@ void ExInfo::UnwindExInfo(VOID* limit)
     {
         NOTHROW; // This function does not throw.
         GC_NOTRIGGER;
-        if (GetThread() != NULL) MODE_COOPERATIVE; else MODE_ANY;
+        if (GetThreadNULLOk() != NULL) MODE_COOPERATIVE; else MODE_ANY;
     }
     CONTRACTL_END;
 
@@ -173,7 +173,7 @@ void ExInfo::UnwindExInfo(VOID* limit)
 #ifdef DEBUGGING_SUPPORTED
     // The debugger thread will be using this, even though it has no
     // Thread object associated with it.
-    _ASSERTE((GetThread() != NULL && GetThread()->PreemptiveGCDisabled()) ||
+    _ASSERTE((GetThreadNULLOk() != NULL && GetThread()->PreemptiveGCDisabled()) ||
              ((g_pDebugInterface != NULL) && (g_pDebugInterface->GetRCThreadId() == GetCurrentThreadId())));
 #endif // DEBUGGING_SUPPORTED
 
index 992cd36..fc3df10 100644 (file)
@@ -533,8 +533,6 @@ ThreadExceptionFlagHolder::ThreadExceptionFlagHolder(ThreadExceptionState::Threa
     WRAPPER_NO_CONTRACT;
 
     Thread* pThread = GetThread();
-    _ASSERTE(pThread);
-
     m_pExState = pThread->GetExceptionState();
 
     m_flag = flag;
index 6e595c0..67ea3fe 100644 (file)
@@ -257,10 +257,7 @@ FCallTransitionState::FCallTransitionState ()
     WRAPPER_NO_CONTRACT;
 
     m_pThread = GetThread();
-    _ASSERTE(m_pThread);
-
     m_pPreviousHelperMethodFrameCallerList = m_pThread->m_pHelperMethodFrameCallerList;
-
     m_pThread->m_pHelperMethodFrameCallerList = NULL;
 }
 
@@ -278,8 +275,6 @@ PermitHelperMethodFrameState::PermitHelperMethodFrameState ()
     WRAPPER_NO_CONTRACT;
 
     m_pThread = GetThread();
-    _ASSERTE(m_pThread);
-
     CONSISTENCY_CHECK_MSG((HelperMethodFrameCallerList*)-1 != m_pThread->m_pHelperMethodFrameCallerList,
                           "fcall entry point is missing a FCALL_TRANSITION_BEGIN or a FCIMPL\n");
 
@@ -320,8 +315,6 @@ VOID PermitHelperMethodFrameState::CheckHelperMethodFramePermitted ()
     //
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
     HelperMethodFrameCallerList *pList = pThread->m_pHelperMethodFrameCallerList;
     PCODE CurrentIP;
     TADDR CurrentSP;
@@ -378,10 +371,7 @@ CompletedFCallTransitionState::CompletedFCallTransitionState ()
     WRAPPER_NO_CONTRACT;
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
     m_pLastHelperMethodFrameCallerList = pThread->m_pHelperMethodFrameCallerList;
-
     pThread->m_pHelperMethodFrameCallerList = (HelperMethodFrameCallerList*)-1;
 }
 
@@ -391,8 +381,6 @@ CompletedFCallTransitionState::~CompletedFCallTransitionState ()
     WRAPPER_NO_CONTRACT;
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
     pThread->m_pHelperMethodFrameCallerList = m_pLastHelperMethodFrameCallerList;
 }
 
index 26afdc9..b09b028 100644 (file)
@@ -35,7 +35,7 @@ BOOL FinalizerThread::IsCurrentThreadFinalizer()
 {
     LIMITED_METHOD_CONTRACT;
 
-    return GetThread() == g_pFinalizerThread;
+    return GetThreadNULLOk() == g_pFinalizerThread;
 }
 
 void FinalizerThread::EnableFinalization()
@@ -489,8 +489,6 @@ void FinalizerThread::FinalizerThreadWait(DWORD timeout)
 
         GCX_PREEMP();
 
-        Thread *pThread = GetThread();
-
         ULONGLONG startTime = CLRGetTickCount64();
         ULONGLONG endTime;
         if (timeout == INFINITE)
index fdfc2ab..5beabd3 100644 (file)
@@ -55,7 +55,7 @@ public:
         EnableFinalization();
 
         // Do not wait for FinalizerThread if the current one is FinalizerThread.
-        if (GetThread() != GetFinalizerThread())
+        if (GetThreadNULLOk() != GetFinalizerThread())
         {
             // This wait must be alertable to handle cases where the current
             // thread's context is needed (i.e. RCW cleanup)
index 1908bc7..10ba921 100644 (file)
@@ -1509,7 +1509,7 @@ struct IsObjRefProtectedScanContext : public ScanContext
     BOOL        oref_protected;
     IsObjRefProtectedScanContext (OBJECTREF * oref)
     {
-        thread_under_crawl = GetThread ();
+        thread_under_crawl = GetThread();
         promotion = TRUE;
         oref_to_check = oref;
         oref_protected = FALSE;
index 64f8613..9765633 100644 (file)
@@ -1312,7 +1312,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs)
 
     BYTE * savedInstrPtr = &gcCover->savedCode[offset];
 
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (!pThread)
     {
         // No thread at the moment so we aren't doing coverage for this function.
@@ -1400,7 +1400,6 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion)
     DWORD offset = codeInfo.GetRelOffset();
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
 
     // There is a race condition with the computation of `atCall`. Multiple threads could enter
     // this function (DoGcStress) at the same time. If one reads `*instrPtr` and sets `atCall`
@@ -1799,4 +1798,3 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion)
 }
 
 #endif // HAVE_GCCOVER
-
index 9c6509d..2318c7b 100644 (file)
@@ -87,7 +87,7 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
     // the threadstore lock.
 
     _ASSERTE(dbgOnly_IsSpecialEEThread() ||
-                GetThread() == NULL ||
+                GetThreadNULLOk() == NULL ||
                 // this is for background GC threads which always call this when EE is suspended.
                 IsGCSpecialThread() ||
                 (GetThread() == ThreadSuspend::GetSuspensionThread() && ThreadStore::HoldingThreadStore()));
@@ -376,7 +376,7 @@ gc_alloc_context * GCToEEInterface::GetAllocContext()
 {
     WRAPPER_NO_CONTRACT;
 
-    Thread* pThread = ::GetThread();
+    Thread* pThread = ::GetThreadNULLOk();
     if (!pThread)
     {
         return nullptr;
@@ -425,7 +425,7 @@ bool GCToEEInterface::IsPreemptiveGCDisabled()
 {
     WRAPPER_NO_CONTRACT;
 
-    Thread* pThread = ::GetThread();
+    Thread* pThread = ::GetThreadNULLOk();
     
     return (pThread && pThread->PreemptiveGCDisabled());
 }
@@ -434,7 +434,7 @@ bool GCToEEInterface::EnablePreemptiveGC()
 {
     WRAPPER_NO_CONTRACT;
 
-    Thread* pThread = ::GetThread();
+    Thread* pThread = ::GetThreadNULLOk();
 
     if (pThread && pThread->PreemptiveGCDisabled())
     {
@@ -449,7 +449,7 @@ void GCToEEInterface::DisablePreemptiveGC()
 {
     WRAPPER_NO_CONTRACT;
 
-    Thread* pThread = ::GetThread();
+    Thread* pThread = ::GetThreadNULLOk();
     if (pThread)
     {
         pThread->DisablePreemptiveGC();
@@ -460,7 +460,7 @@ Thread* GCToEEInterface::GetThread()
 {
     WRAPPER_NO_CONTRACT;
 
-    return ::GetThread();
+    return ::GetThreadNULLOk();
 }
 
 //
@@ -1689,4 +1689,3 @@ void GCToEEInterface::LogStressMsg(unsigned level, unsigned facility, const Stre
 {
     StressLog::LogMsg(level, facility, msg);
 }
-
index 30c3ca7..7980a43 100644 (file)
@@ -464,7 +464,7 @@ namespace _GCStress
             GcStressBase::MaybeTrigger(acontext);
 
 #ifdef _DEBUG
-            Thread *pThread = GetThread();
+            Thread *pThread = GetThreadNULLOk();
             if (pThread)
             {
                 pThread->EnableStressHeap();
index a6708d2..1b0c697 100644 (file)
@@ -101,7 +101,7 @@ PTR_Bucket HashMap::Buckets()
     LIMITED_METHOD_DAC_CONTRACT;
 
 #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-    _ASSERTE (!g_fEEStarted || !m_fAsyncMode || GetThread() == NULL || GetThread()->PreemptiveGCDisabled() || IsGCThread());
+    _ASSERTE (!g_fEEStarted || !m_fAsyncMode || GetThreadNULLOk() == NULL || GetThread()->PreemptiveGCDisabled() || IsGCThread());
 #endif
     return m_rgBuckets + 1;
 }
@@ -872,7 +872,7 @@ void HashMap::Rehash()
     GCX_MAYBE_COOP_NO_THREAD_BROKEN(m_fAsyncMode);
 
 #ifndef CROSSGEN_COMPILE
-    _ASSERTE (!g_fEEStarted || !m_fAsyncMode || GetThread() == NULL || GetThread()->PreemptiveGCDisabled());
+    _ASSERTE (!g_fEEStarted || !m_fAsyncMode || GetThreadNULLOk() == NULL || GetThread()->PreemptiveGCDisabled());
     _ASSERTE (OwnLock());
 #endif
 
index f843926..66896fe 100644 (file)
@@ -274,7 +274,7 @@ BOOL __SwitchToThread (DWORD dwSleepMSec, DWORD dwSwitchCount)
         NOTHROW;
         GC_NOTRIGGER;
         MODE_ANY;
-        PRECONDITION(dwSleepMSec < 10000 || GetThread() == NULL || !GetThread()->PreemptiveGCDisabled());
+        PRECONDITION(dwSleepMSec < 10000 || GetThreadNULLOk() == NULL || !GetThread()->PreemptiveGCDisabled());
     }
     CONTRACTL_END;
 
index 75e42c2..3d2e0e4 100644 (file)
@@ -172,7 +172,7 @@ Frame *GetCurrFrame(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame)
         pFrame = ((FrameHandlerExRecord *)pEstablisherFrame)->GetCurrFrame();
 
     // Assert that the exception frame is on the thread or that the exception frame is the top frame.
-    _ASSERTE(GetThread() == NULL || GetThread()->GetFrame() == (Frame*)-1 || GetThread()->GetFrame() <= pFrame);
+    _ASSERTE(GetThreadNULLOk() == NULL || GetThread()->GetFrame() == (Frame*)-1 || GetThread()->GetFrame() <= pFrame);
 
     return pFrame;
 }
@@ -280,7 +280,7 @@ void VerifyValidTransitionFromManagedCode(Thread *pThread, CrawlFrame *pCF)
     _ASSERTE(ExecutionManager::IsManagedCode(GetControlPC(pCF->GetRegisterSet())));
 
     // Cannot get to the TEB of other threads. So ignore them.
-    if (pThread != GetThread())
+    if (pThread != GetThreadNULLOk())
     {
         return;
     }
@@ -1864,7 +1864,6 @@ LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVO
     // Set up m_OSContext for the call to COMPlusCheckForAbort
     //
     Thread* pThread = GetThread();
-    _ASSERTE(pThread != NULL);
 
     SetIP(pThread->m_OSContext, (PCODE)*pRetAddress);
     SetSP(pThread->m_OSContext, (TADDR)esp);
@@ -3304,7 +3303,6 @@ EXCEPTION_HANDLER_IMPL(COMPlusNestedExceptionHandler)
         // the unwind.
 
         Thread* pThread = GetThread();
-        _ASSERTE(pThread);
         ExInfo* pExInfo = &(pThread->GetExceptionState()->m_currentExInfo);
         ExInfo* pPrevNestedInfo = pExInfo->m_pPrevNestedInfo;
 
@@ -3424,7 +3422,6 @@ EXCEPTION_HANDLER_IMPL(UMThunkPrestubHandler)
         GCX_COOP();     // Must be cooperative to modify frame chain.
 
         Thread *pThread = GetThread();
-        _ASSERTE(pThread);
         Frame *pFrame = pThread->GetFrame();
         pFrame->ExceptionUnwind();
         pFrame->Pop(pThread);
@@ -3503,7 +3500,7 @@ AdjustContextForVirtualStub(
 {
     LIMITED_METHOD_CONTRACT;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     // We may not have a managed thread object. Example is an AV on the helper thread.
     // (perhaps during StubManager::IsStub)
index 4cba116..cefe7ec 100644 (file)
@@ -1226,7 +1226,7 @@ int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {GC_NOTRIGGER;}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {GC_NOTRIGGER;}
     } CONTRACTL_END;
 
     int stompWBCompleteActions = SWB_PASS;
@@ -1253,7 +1253,7 @@ int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck)
             // Check if we need to use the upper bounds checking barrier stub.
             if (bReqUpperBoundsCheck)
             {
-                GCX_MAYBE_COOP_NO_THREAD_BROKEN((GetThread()!=NULL));
+                GCX_MAYBE_COOP_NO_THREAD_BROKEN((GetThreadNULLOk()!=NULL));
                 if( !isRuntimeSuspended && !(stompWBCompleteActions & SWB_EE_RESTART) ) {
                     ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_FOR_GC_PREP);
                     stompWBCompleteActions |= SWB_EE_RESTART;
index e6753a6..8817bf1 100644 (file)
@@ -2412,7 +2412,7 @@ VOID StubLinkerCPU::X86EmitCurrentThreadFetch(X86Reg dstreg, unsigned preservedR
     X86EmitPushRegs(preservedRegSet & ((1 << kEAX) | (1 << kEDX) | (1 << kECX)));
 
     // call GetThread
-    X86EmitCall(NewExternalCodeLabel((LPVOID)GetThread), sizeof(void*));
+    X86EmitCall(NewExternalCodeLabel((LPVOID)GetThreadHelper), sizeof(void*));
 
     // mov dstreg, eax
     X86EmitMovRegReg(dstreg, kEAX);
index eded148..e564c9a 100644 (file)
@@ -146,7 +146,7 @@ void IBCLogger::LogAccessThreadSafeHelper(const void * p, pfnIBCAccessCallback c
     if (p == NULL)
         return;
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
     /* This could be called by the concurrent GC thread*/
     /* where GetThread() returns NULL. In such cases,*/
index 90f1149..a2d46af 100644 (file)
@@ -210,7 +210,7 @@ void FillExceptionData(
 
     if (pErrInfo != NULL)
     {
-        Thread* pThread = GetThread();
+        Thread* pThread = GetThreadNULLOk();
         if (pThread != NULL)
         {
             GCX_PREEMP();
@@ -1471,7 +1471,7 @@ VOID EnsureComStarted(BOOL fCoInitCurrentThread)
         THROWS;
         GC_TRIGGERS;
         MODE_ANY;
-        PRECONDITION(GetThread() || !fCoInitCurrentThread);
+        PRECONDITION(GetThreadNULLOk() || !fCoInitCurrentThread);
         PRECONDITION(g_fEEStarted);
     }
     CONTRACTL_END;
@@ -1502,7 +1502,7 @@ HRESULT EnsureComStartedNoThrow(BOOL fCoInitCurrentThread)
         GC_TRIGGERS;
         MODE_ANY;
         PRECONDITION(g_fEEStarted);
-        PRECONDITION(GetThread() != NULL);      // Should always be inside BEGIN_EXTERNAL_ENTRYPOINT
+        PRECONDITION(GetThreadNULLOk() != NULL);      // Should always be inside BEGIN_EXTERNAL_ENTRYPOINT
     }
     CONTRACTL_END;
 
index 325aaf4..17c27e6 100644 (file)
@@ -3313,8 +3313,6 @@ bool Interpreter::MethodHandlesException(OBJECTREF orThrowable)
 
     if (orThrowable != NULL)
     {
-        PTR_Thread pCurThread = GetThread();
-
         // Don't catch ThreadAbort and other uncatchable exceptions
         if (!IsUncatchable(&orThrowable))
         {
index b2d5417..9dbdeab 100644 (file)
@@ -3946,7 +3946,6 @@ HCIMPL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock)
     MONHELPER_STATE(_ASSERTE(pbLockTaken != NULL && *pbLockTaken == 0));
 
     Thread *pCurThread = GetThread();
-
     if (pCurThread->CatchAtSafePointOpportunistic())
     {
         goto FramedLockHelper;
index d9b7351..798d594 100644 (file)
@@ -63,7 +63,7 @@ void* JitHost::allocateSlab(size_t size, size_t* pActualSize)
 {
     size = max(size, sizeof(Slab));
 
-    Thread* pCurrentThread = GetThread();
+    Thread* pCurrentThread = GetThreadNULLOk();
     if (m_pCurrentCachedList != NULL || m_pPreviousCachedList != NULL)
     {
         CrstHolder lock(&m_jitSlabAllocatorCrst);
@@ -124,7 +124,7 @@ void JitHost::freeSlab(void* slab, size_t actualSize)
 
             Slab* pSlab = (Slab*)slab;
             pSlab->size = actualSize;
-            pSlab->affinity = GetThread();
+            pSlab->affinity = GetThreadNULLOk();
             pSlab->pNext = m_pCurrentCachedList;
             m_pCurrentCachedList = pSlab;
             return;
index 2c91f19..2a3b251 100644 (file)
@@ -76,7 +76,6 @@
 //
 
 #define JIT_TO_EE_TRANSITION()          MAKE_CURRENT_THREAD_AVAILABLE_EX(m_pThread);                \
-                                        _ASSERTE(CURRENT_THREAD == GetThread());                    \
                                         INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE;               \
                                         COOPERATIVE_TRANSITION_BEGIN();                             \
 
index e98cd19..719bda0 100644 (file)
@@ -505,7 +505,7 @@ public:
         m_pOverride(NULL),
         m_pMethodBeingCompiled(fd),
         m_fVerifyOnly(fVerifyOnly),
-        m_pThread(GetThread()),
+        m_pThread(GetThreadNULLOk()),
         m_hMethodForSecurity_Key(NULL),
         m_pMethodForSecurity_Value(NULL),
 #if defined(FEATURE_GDBJIT)
index 7652aa8..a6f1048 100644 (file)
@@ -3186,9 +3186,7 @@ void MethodTable::DoRunClassInitThrowing()
     // policy, keep this unless it proves intractable to remove all premature classinits in the system.
     EnsureActive();
 
-    Thread *pThread;
-    pThread = GetThread();
-    _ASSERTE(pThread);
+    Thread* pThread = GetThread();
 
     AppDomain *pDomain = GetAppDomain();
 
@@ -3633,7 +3631,7 @@ void CallFinalizerOnThreadObject(Object *obj)
         // finalization.
         if ((g_fEEShutDown & ShutDown_Finalize2) == 0)
         {
-            if (GetThread() != thread)
+            if (GetThreadNULLOk() != thread)
             {
                 refThis->ClearInternal();
             }
index b0c7b45..7ad0260 100644 (file)
@@ -11592,7 +11592,7 @@ MethodTableBuilder::GatherGenericsInfo(
     CONTRACTL
     {
         STANDARD_VM_CHECK;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(CheckPointer(pModule));
         PRECONDITION(CheckPointer(bmtGenericsInfo));
     }
@@ -11840,7 +11840,7 @@ ClassLoader::CreateTypeHandleForTypeDefThrowing(
     CONTRACT(TypeHandle)
     {
         STANDARD_VM_CHECK;
-        PRECONDITION(GetThread() != NULL);
+        PRECONDITION(GetThreadNULLOk() != NULL);
         PRECONDITION(CheckPointer(pModule));
         POSTCONDITION(!RETVAL.IsNull());
         POSTCONDITION(CheckPointer(RETVAL.GetMethodTable()));
index 46a8600..9440f8d 100644 (file)
@@ -33,8 +33,6 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
     Thread *pThread = GetThread();
     size_t key=0;
 
-    _ASSERTE(pThread);
-
     //Poll and wait if GC is in progress, to avoid blocking GC for too long.
     FC_GC_POLL();
 
index fad929a..36b100d 100644 (file)
@@ -464,8 +464,7 @@ VOID Object::Validate(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncBlock)
 
 #ifdef _DEBUG
     {
-        BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
 
         if (pThread != NULL && !(pThread->PreemptiveGCDisabled()))
         {
@@ -480,7 +479,6 @@ VOID Object::Validate(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncBlock)
             if (!dbgOnly_IsSpecialEEThread() && !IsGCSpecialThread())
                 _ASSERTE(!"OBJECTREF being accessed while thread is in preemptive GC mode.");
         }
-        END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
     }
 #endif
 
@@ -1303,7 +1301,7 @@ void* __cdecl GCSafeMemCpy(void * dest, const void * src, size_t len)
     if (!(((*(BYTE**)&dest) <  g_lowest_address ) ||
           ((*(BYTE**)&dest) >= g_highest_address)))
     {
-        Thread* pThread = GetThread();
+        Thread* pThread = GetThreadNULLOk();
 
         // GCHeapUtilities::IsHeapPointer has race when called in preemptive mode. It walks the list of segments
         // that can be modified by GC. Do the check below only if it is safe to do so.
@@ -1388,7 +1386,7 @@ void StackTraceArray::CheckState() const
     if (!m_array)
         return;
 
-    assert(GetObjectThread() == GetThread());
+    assert(GetObjectThread() == GetThreadNULLOk());
 
     size_t size = Size();
     StackTraceElement const * p;
@@ -1443,7 +1441,7 @@ void StackTraceArray::EnsureThreadAffinity()
     if (!m_array)
         return;
 
-    if (GetObjectThread() != GetThread())
+    if (GetObjectThread() != GetThreadNULLOk())
     {
         // object is being changed by a thread different from the one which created it
         // make a copy of the array to prevent a race condition when two different threads try to change it
index 375691a..01fa328 100644 (file)
@@ -1921,7 +1921,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
 
     ETWOnStartup(PrestubWorker_V1, PrestubWorkerEnd_V1);
 
-    MAKE_CURRENT_THREAD_AVAILABLE();
+    MAKE_CURRENT_THREAD_AVAILABLE_EX(GetThreadNULLOk());
 
     // Attempt to check what GC mode we are running under.
     if (CURRENT_THREAD == NULL
index 364f574..f642630 100644 (file)
@@ -18,8 +18,7 @@ FORCEINLINE SetCallbackStateFlagsHolder::SetCallbackStateFlagsHolder(DWORD dwFla
 {
     // This is called before entering a profiler.  We set the specified dwFlags on
     // the Thread object, and remember the previous flags for later.
-    BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-    m_pThread = GetThread();
+    m_pThread = GetThreadNULLOk();
     if (m_pThread != NULL)
     {
         m_dwOriginalFullState = m_pThread->SetProfilerCallbackStateFlags(dwFlags);
@@ -28,7 +27,6 @@ FORCEINLINE SetCallbackStateFlagsHolder::SetCallbackStateFlagsHolder(DWORD dwFla
     {
         m_dwOriginalFullState = 0;
     }
-    END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
 }
 
 FORCEINLINE SetCallbackStateFlagsHolder::~SetCallbackStateFlagsHolder()
@@ -44,9 +42,7 @@ FORCEINLINE SetCallbackStateFlagsHolder::~SetCallbackStateFlagsHolder()
     // original flag set here.
     if (m_pThread != NULL)
     {
-        BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
         m_pThread->SetProfilerCallbackFullState(m_dwOriginalFullState);
-        END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
     }
 }
 
index ac4d9c7..ccf2af5 100644 (file)
@@ -3000,7 +3000,7 @@ HRESULT ProfToEEInterfaceImpl::GetRVAStaticAddress(ClassID classId,
         return E_INVALIDARG;
     }
 
-    if (GetThread() == NULL)
+    if (GetThreadNULLOk() == NULL)
     {
         return CORPROF_E_NOT_MANAGED_THREAD;
     }
@@ -3275,12 +3275,12 @@ HRESULT ProfToEEInterfaceImpl::GetThreadStaticAddress(ClassID classId,
     //
     // Verify the value of threadId, which must be the current thread ID or NULL, which means using curernt thread ID.
     //
-    if ((threadId != NULL) && (threadId != ((ThreadID)GetThread())))
+    if ((threadId != NULL) && (threadId != ((ThreadID)GetThreadNULLOk())))
     {
         return E_INVALIDARG;
     }
 
-    threadId = reinterpret_cast<ThreadID>(GetThread());
+    threadId = reinterpret_cast<ThreadID>(GetThreadNULLOk());
     AppDomainID appDomainId = reinterpret_cast<AppDomainID>(GetAppDomain());
 
     //
@@ -3352,12 +3352,12 @@ HRESULT ProfToEEInterfaceImpl::GetThreadStaticAddress2(ClassID classId,
 
     if (threadId == NULL)
     {
-        if (GetThread() == NULL)
+        if (GetThreadNULLOk() == NULL)
         {
             return CORPROF_E_NOT_MANAGED_THREAD;
         }
 
-        threadId = reinterpret_cast<ThreadID>(GetThread());
+        threadId = reinterpret_cast<ThreadID>(GetThreadNULLOk());
     }
 
     //
@@ -8914,7 +8914,7 @@ HRESULT ProfToEEInterfaceImpl::GetNotifiedExceptionClauseInfo(COR_PRF_EX_CLAUSE_
     EHClauseInfo*         pCurrentEHClauseInfo = NULL;
 
     // notification requires that we are on a managed thread with an exception in flight
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
 
     // If pThread is null, then the thread has never run managed code
     if (pThread == NULL)
@@ -8985,9 +8985,9 @@ HRESULT ProfToEEInterfaceImpl::GetObjectGeneration(ObjectID objectId,
                                        "**PROF: GetObjectGeneration 0x%p.\n",
                                        objectId));
 
-    BEGIN_GETTHREAD_ALLOWED;
-    _ASSERTE((GetThread() == NULL) || (GetThread()->PreemptiveGCDisabled()));
-    END_GETTHREAD_ALLOWED;
+    
+    _ASSERTE((GetThreadNULLOk() == NULL) || (GetThreadNULLOk()->PreemptiveGCDisabled()));
+    
 
     // Announce we are using the generation table now
     CounterHolder genTableLock(&s_generationTableLock);
@@ -9076,12 +9076,12 @@ HRESULT ProfToEEInterfaceImpl::SetupThreadForReJIT()
     HRESULT hr = S_OK;
     EX_TRY
     {
-        if (GetThread() == NULL)
+        if (GetThreadNULLOk() == NULL)
         {
             SetupThread();
         }
 
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         pThread->SetProfilerCallbackStateFlags(COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED);
     }
     EX_CATCH_HRESULT(hr);
@@ -10102,7 +10102,7 @@ HRESULT ProfToEEInterfaceImpl::InitializeCurrentThread()
             LL_INFO10,
             "**PROF: InitializeCurrentThread.\n"));
 
-    SetupTLSForThread(GetThread());
+    SetupTLSForThread();
 
     return S_OK;
 }
index 929dd70..18404df 100644 (file)
@@ -60,7 +60,6 @@ inline BOOL AreCallbackStateFlagsSet(DWORD dwFlags)
     }
 
     BOOL fRet;
-    BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
     DWORD dwProfilerCallbackFullStateFlags = pThread->GetProfilerCallbackFullState();
     if (((dwProfilerCallbackFullStateFlags & COR_PRF_CALLBACKSTATE_FORCEGC_WAS_CALLED) != 0)
         || ((dwProfilerCallbackFullStateFlags & COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED) != 0))
@@ -71,7 +70,6 @@ inline BOOL AreCallbackStateFlagsSet(DWORD dwFlags)
     }
 
     fRet = ((dwProfilerCallbackFullStateFlags & dwFlags) == dwFlags);
-    END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
     return fRet;
 }
 
index c26f311..17f58b0 100644 (file)
@@ -1241,7 +1241,7 @@ HRESULT RCWCleanupList::ReleaseRCWListInCorrectCtx(LPVOID pData)
     // into cooperative GC mode. This "fix" will prevent us from doing so.
     if (g_fEEShutDown & ShutDown_Finalize2)
     {
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (pThread && !FinalizerThread::IsCurrentThreadFinalizer())
             pThread->SetThreadStateNC(Thread::TSNC_UnsafeSkipEnterCooperative);
     }
@@ -1254,7 +1254,7 @@ HRESULT RCWCleanupList::ReleaseRCWListInCorrectCtx(LPVOID pData)
     //  the MTA context), we will infinitely loop.  So, we short circuit this with ctxTried.
 
     Thread *pHeadThread = pHead->GetSTAThread();
-    BOOL fCorrectThread = (pHeadThread == NULL) ? TRUE : (pHeadThread == GetThread());
+    BOOL fCorrectThread = (pHeadThread == NULL) ? TRUE : (pHeadThread == GetThreadNULLOk());
     BOOL fCorrectCookie = (pCurrCtxCookie == NULL) ? TRUE : (pHead->GetWrapperCtxCookie() == pCurrCtxCookie);
 
     if ( pHead->IsFreeThreaded() || // Avoid context transition if the list is for free threaded RCW
@@ -1281,7 +1281,7 @@ HRESULT RCWCleanupList::ReleaseRCWListInCorrectCtx(LPVOID pData)
     // Reset the bit indicating we cannot transition into cooperative GC mode.
     if (g_fEEShutDown & ShutDown_Finalize2)
     {
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (pThread && !FinalizerThread::IsCurrentThreadFinalizer())
             pThread->ResetThreadStateNC(Thread::TSNC_UnsafeSkipEnterCooperative);
     }
@@ -1433,7 +1433,6 @@ void RCW::Initialize(IUnknown* pUnk, DWORD dwSyncBlockIndex, MethodTable *pClass
     // if this thread is an STA thread, then when the STA dies
     // we need to cleanup this wrapper
     m_pCreatorThread  = GetThread();
-    _ASSERTE(m_pCreatorThread != NULL);
 
     m_pRCWCache = RCWCache::GetRCWCache();
 
index b434e7b..dfe54a9 100644 (file)
@@ -238,9 +238,9 @@ void SimpleRWLock::PreEnter()
     CONTRACTL_END;
 
     if (m_gcMode == PREEMPTIVE)
-        _ASSERTE(!GetThread() || !GetThread()->PreemptiveGCDisabled());
+        _ASSERTE(!GetThreadNULLOk() || !GetThread()->PreemptiveGCDisabled());
     else if (m_gcMode == COOPERATIVE)
-        _ASSERTE(!GetThread() || GetThread()->PreemptiveGCDisabled());
+        _ASSERTE(!GetThreadNULLOk() || GetThread()->PreemptiveGCDisabled());
 }
 
 //=====================================================================
index 2d7542b..c917319 100644 (file)
@@ -277,7 +277,7 @@ void SpinLock::dbg_PreEnterLock()
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread)
     {
         // SpinLock can not be nested.
@@ -300,7 +300,7 @@ void SpinLock::dbg_EnterLock()
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread)
     {
         INCONTRACT(pThread->BeginNoTriggerGC(__FILE__, __LINE__));
@@ -317,7 +317,7 @@ void SpinLock::dbg_LeaveLock()
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread)
     {
         _ASSERTE ((pThread->m_StateNC & Thread::TSNC_OwnsSpinLock) != 0);
index a13127e..7e1339f 100644 (file)
@@ -946,7 +946,7 @@ StackWalkAction Thread::StackWalkFrames(PSTACKWALKFRAMESCALLBACK pCallback,
     bool fUseInitRegDisplay;
 
 #ifndef DACCESS_COMPILE
-    _ASSERTE(GetThread() == this || (flags & ALLOW_ASYNC_STACK_WALK));
+    _ASSERTE(GetThreadNULLOk() == this || (flags & ALLOW_ASYNC_STACK_WALK));
     BOOL fDebuggerHasInitialContext = (GetFilterContext() != NULL);
     BOOL fProfilerHasInitialContext = (GetProfilerFilterContext() != NULL);
 
index ef30622..2262273 100644 (file)
@@ -217,7 +217,7 @@ public:
         CONTRACTL
         {
             NOTHROW;
-            if(GetThread()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
+            if(GetThreadNULLOk()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
             PRECONDITION(CheckPointer(this));
         }
         CONTRACTL_END;
@@ -232,7 +232,7 @@ public:
         CONTRACTL
         {
             NOTHROW;
-            if(GetThread()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
+            if(GetThreadNULLOk()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
             PRECONDITION(CheckPointer(this));
         }
         CONTRACTL_END;
@@ -244,7 +244,7 @@ public:
         CONTRACTL
         {
             NOTHROW;
-            if(GetThread()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
+            if(GetThreadNULLOk()){GC_NOTRIGGER;}else{DISABLED(GC_TRIGGERS);};
             MODE_COOPERATIVE;
             PRECONDITION(CheckPointer(this));
             PRECONDITION(CheckPointer(pStringData));
index 55736ec..a86cd61 100644 (file)
@@ -1692,7 +1692,7 @@ BOOL ObjHeader::LeaveObjMonitor()
 
     for (;;)
     {
-        AwareLock::LeaveHelperAction action = thisObj->GetHeader ()->LeaveObjMonitorHelper(GetThread());
+        AwareLock::LeaveHelperAction action = thisObj->GetHeader()->LeaveObjMonitorHelper(GetThread());
 
         switch(action)
         {
@@ -1923,7 +1923,7 @@ DEBUG_NOINLINE void ObjHeader::EnterSpinLock()
             __SwitchToThread(0, ++dwSwitchCount);
     }
 
-    INCONTRACT(Thread* pThread = GetThread());
+    INCONTRACT(Thread* pThread = GetThreadNULLOk());
     INCONTRACT(if (pThread != NULL) pThread->BeginNoTriggerGC(__FILE__, __LINE__));
 }
 #else
@@ -1959,7 +1959,7 @@ DEBUG_NOINLINE void ObjHeader::EnterSpinLock()
         __SwitchToThread(0, ++dwSwitchCount);
     }
 
-    INCONTRACT(Thread* pThread = GetThread());
+    INCONTRACT(Thread* pThread = GetThreadNULLOk());
     INCONTRACT(if (pThread != NULL) pThread->BeginNoTriggerGC(__FILE__, __LINE__));
 }
 #endif //MP_LOCKS
@@ -1969,7 +1969,7 @@ DEBUG_NOINLINE void ObjHeader::ReleaseSpinLock()
     SCAN_SCOPE_END;
     LIMITED_METHOD_CONTRACT;
 
-    INCONTRACT(Thread* pThread = GetThread());
+    INCONTRACT(Thread* pThread = GetThreadNULLOk());
     INCONTRACT(if (pThread != NULL) pThread->EndNoTriggerGC());
 
     FastInterlockAnd(&m_SyncBlockValue, ~BIT_SBLK_SPIN_LOCK);
@@ -2953,4 +2953,3 @@ void ObjHeader::IllegalAlignPad()
 }
 #endif // HOST_64BIT && _DEBUG
 
-
index 55e8dec..4ffb3d2 100644 (file)
@@ -30,9 +30,7 @@ void SyncClean::AddHashMap (Bucket *bucket)
         return;
     }
 
-    BEGIN_GETTHREAD_ALLOWED
-    _ASSERTE (GetThread() == NULL || GetThread()->PreemptiveGCDisabled());
-    END_GETTHREAD_ALLOWED
+    _ASSERTE (GetThreadNULLOk() == NULL || GetThread()->PreemptiveGCDisabled());
 
     Bucket * pTempBucket = NULL;
     do
@@ -52,9 +50,7 @@ void SyncClean::AddEEHashTable (EEHashEntry** entry)
         return;
     }
 
-    BEGIN_GETTHREAD_ALLOWED
-    _ASSERTE (GetThread() == NULL || GetThread()->PreemptiveGCDisabled());
-    END_GETTHREAD_ALLOWED
+    _ASSERTE (GetThreadNULLOk() == NULL || GetThread()->PreemptiveGCDisabled());
 
     EEHashEntry ** pTempHashEntry = NULL;
     do
@@ -72,7 +68,7 @@ void SyncClean::CleanUp ()
     // Only GC thread can call this.
     _ASSERTE (g_fProcessDetach ||
               IsGCSpecialThread() ||
-              (GCHeapUtilities::IsGCInProgress()  && GetThread() == ThreadSuspend::GetSuspensionThread()));
+              (GCHeapUtilities::IsGCInProgress()  && GetThreadNULLOk() == ThreadSuspend::GetSuspensionThread()));
     if (m_HashMap)
     {
         Bucket * pTempBucket = FastInterlockExchangePointer(m_HashMap.GetPointer(), NULL);
index bc60f8c..2f9acbe 100644 (file)
@@ -118,7 +118,7 @@ void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
         GC_NOTRIGGER;
         // disallow creation of Crst before EE starts
         PRECONDITION((g_fEEStarted));
-        PRECONDITION((GetThread() != NULL));
+        PRECONDITION((GetThreadNULLOk() != NULL));
         PRECONDITION((!IsOSEvent()));
     }
     CONTRACTL_END;
@@ -426,7 +426,7 @@ DWORD CLREventBase::WaitEx(DWORD dwMilliseconds, WaitMode mode, PendingSync *syn
         {
             NOTHROW;
         }
-        if (GetThread())
+        if (GetThreadNULLOk())
         {
             if (alertable)
                 GC_TRIGGERS;
@@ -444,7 +444,7 @@ DWORD CLREventBase::WaitEx(DWORD dwMilliseconds, WaitMode mode, PendingSync *syn
 
     _ASSERTE(Thread::Debug_AllowCallout());
 
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
 
 #ifdef _DEBUG
     // If a CLREvent is OS event only, we can not wait for the event on a managed thread
@@ -518,7 +518,7 @@ DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
 {
     CONTRACTL
     {
-        if (GetThread() && alertable)
+        if (GetThreadNULLOk() && alertable)
         {
             THROWS;               // Thread::DoAppropriateWait can throw
         }
@@ -526,7 +526,8 @@ DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
         {
             NOTHROW;
         }
-        if (GetThread())
+
+        if (GetThreadNULLOk())
         {
             if (alertable)
                 GC_TRIGGERS;
@@ -537,12 +538,13 @@ DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
         {
             DISABLED(GC_TRIGGERS);
         }
+
         PRECONDITION(m_handle != INVALID_HANDLE_VALUE); // Invalid to have invalid handle
     }
     CONTRACTL_END;
 
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     _ASSERTE (pThread || !g_fEEStarted || dbgOnly_IsSpecialEEThread());
 
     {
index 0e918a3..ff3fc9c 100644 (file)
@@ -525,7 +525,7 @@ void UnManagedPerAppDomainTPCount::DispatchWorkItem(bool* foundWork, bool* wasNo
         }
         *wasNotRecalled = ThreadpoolMgr::ShouldWorkerKeepRunning();
 
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (pThread)
         {
             _ASSERTE(!pThread->IsAbortRequested());
@@ -631,7 +631,7 @@ void ManagedPerAppDomainTPCount::DispatchWorkItem(bool* foundWork, bool* wasNotR
     *wasNotRecalled = true;
 
     HRESULT hr;
-    Thread * pThread = GetThread();
+    Thread * pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         ClrFlsSetThreadType(ThreadType_Threadpool_Worker);
index 2bcc4ed..62f2b7e 100644 (file)
@@ -60,6 +60,11 @@ TailCallTls::TailCallTls()
 {
 }
 
+Thread* STDCALL GetThreadHelper()
+{
+    return GetThreadNULLOk();
+}
+
 TailCallArgBuffer* TailCallTls::AllocArgBuffer(int size, void* gcDesc)
 {
     CONTRACTL
@@ -406,13 +411,13 @@ DWORD Thread::JoinEx(DWORD timeout, WaitMode mode)
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
     BOOL alertable = (mode & WaitMode_Alertable)?TRUE:FALSE;
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     _ASSERTE(pCurThread || dbgOnly_IsSpecialEEThread());
 
     {
@@ -593,13 +598,13 @@ Thread* SetupThreadNoThrow(HRESULT *pHR)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
     HRESULT hr = S_OK;
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread != NULL)
     {
         return pThread;
@@ -635,7 +640,7 @@ void DeleteThread(Thread* pThread)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -668,7 +673,7 @@ void DeleteThread(Thread* pThread)
 void EnsurePreemptive()
 {
     WRAPPER_NO_CONTRACT;
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread && pThread->PreemptiveGCDisabled())
     {
         pThread->EnablePreemptiveGC();
@@ -681,12 +686,12 @@ Thread* SetupThread()
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
     Thread* pThread;
-    if ((pThread = GetThread()) != NULL)
+    if ((pThread = GetThreadNULLOk()) != NULL)
         return pThread;
 
     // For interop debugging, we must mark that we're in a can't-stop region
@@ -768,7 +773,7 @@ Thread* SetupThread()
 
     Holder<Thread*,DoNothing<Thread*>,DeleteThread> threadHolder(pThread);
 
-    SetupTLSForThread(pThread);
+    SetupTLSForThread();
 
     if (!pThread->InitThread() ||
         !pThread->PrepareApartmentAndContext())
@@ -867,7 +872,7 @@ Thread* SetupUnstartedThread(BOOL bRequiresTSL)
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -1184,7 +1189,7 @@ void InitThreadManager()
 #endif // FEATURE_WRITEBARRIER_COPY
 
 #ifndef TARGET_UNIX
-    _ASSERTE(GetThread() == NULL);
+    _ASSERTE(GetThreadNULLOk() == NULL);
 
     size_t offsetOfCurrentThreadInfo = Thread::GetOffsetOfThreadStatic(&gCurrentThreadInfo);
 
@@ -1348,7 +1353,7 @@ Thread::Thread()
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -1557,7 +1562,6 @@ Thread::Thread()
     m_ioThreadPoolCompletionCount = 0;
     m_monitorLockContentionCount = 0;
 
-    Thread *pThread = GetThread();
     InitContext();
 
     // Do not expose thread until it is fully constructed
@@ -1612,7 +1616,7 @@ BOOL Thread::InitThread()
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -1796,11 +1800,11 @@ BOOL Thread::HasStarted(BOOL bRequiresTSL)
     // the runtime.  But sometimes that thread is used for DLL_THREAD_ATTACH notifications
     // that call into managed code.  In that case, the second HasStarted call is
     // redundant and should be ignored.
-    if (GetThread() == this)
+    if (GetThreadNULLOk() == this)
         return TRUE;
 
 
-    _ASSERTE(GetThread() == 0);
+    _ASSERTE(GetThreadNULLOk() == 0);
     _ASSERTE(HasValidThreadHandle());
 
     BOOL    fKeepTLS = FALSE;
@@ -1822,7 +1826,7 @@ BOOL Thread::HasStarted(BOOL bRequiresTSL)
         // Initialization must happen in the following order - hosts like SQL Server depend on this.
         //
 
-        SetupTLSForThread(this);
+        SetupTLSForThread();
 
         fCanCleanupCOMState = TRUE;
         res = PrepareApartmentAndContext();
@@ -1864,7 +1868,7 @@ FAILURE:
 
         SetThreadState(TS_FailStarted);
 
-        if (GetThread() != NULL && IsAbortRequested())
+        if (GetThreadNULLOk() != NULL && IsAbortRequested())
             UnmarkThreadForAbort();
 
         if (!fKeepTLS)
@@ -1977,7 +1981,7 @@ void Thread::HandleThreadStartupFailure()
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
 
     struct ProtectArgs
     {
@@ -2336,11 +2340,11 @@ int Thread::IncExternalCount()
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
 
     _ASSERTE(m_ExternalRefCount > 0);
     int retVal = FastInterlockIncrement((LONG*)&m_ExternalRefCount);
@@ -2367,13 +2371,13 @@ int Thread::DecExternalCount(BOOL holdingLock)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
     // Note that it's possible to get here with a NULL current thread (during
     // shutdown of the thread manager).
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     _ASSERTE (pCurThread == NULL || IsAtProcessExit()
               || (!holdingLock && !ThreadStore::HoldingThreadStore(pCurThread))
               || (holdingLock && ThreadStore::HoldingThreadStore(pCurThread)));
@@ -2535,7 +2539,7 @@ Thread::~Thread()
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -2824,7 +2828,7 @@ void Thread::CleanupCOMState()
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -2871,7 +2875,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -2887,7 +2891,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
     // Should not use OSThreadId:
     // OSThreadId may change for the current thread is the thread is blocked and rescheduled
     // by host.
-    Thread *pCurrentThread = GetThread();
+    Thread *pCurrentThread = GetThreadNULLOk();
     DWORD CurrentThreadID = pCurrentThread?pCurrentThread->GetThreadId():0;
     DWORD ThisThreadID = GetThreadId();
 
@@ -2895,7 +2899,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
     // If the currently running thread is the thread that died and it is an STA thread, then we
     // need to release all the RCW's in the current context. However, we cannot do this if we
     // are in the middle of process detach.
-    if (!IsAtProcessExit() && this == GetThread())
+    if (!IsAtProcessExit() && this == GetThreadNULLOk())
     {
         CleanupCOMState();
     }
@@ -4097,7 +4101,7 @@ void WINAPI Thread::UserInterruptAPC(ULONG_PTR data)
 
     _ASSERTE(data == APC_Code);
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     if (pCurThread)
     {
         // We should only take action if an interrupt is currently being
@@ -4220,7 +4224,7 @@ OBJECTREF Thread::GetExposedObject()
 
     TRIGGERSGC();
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
     _ASSERTE (!(pCurThread == NULL || IsAtProcessExit()));
 
     _ASSERTE(pCurThread->PreemptiveGCDisabled());
@@ -4289,13 +4293,13 @@ void Thread::SetExposedObject(OBJECTREF exposed)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
     if (exposed != NULL)
     {
-        _ASSERTE (GetThread() != this);
+        _ASSERTE (GetThreadNULLOk() != this);
         _ASSERTE(IsUnstarted());
         _ASSERTE(ObjectFromHandle(m_ExposedObject) == NULL);
         // The exposed object keeps us alive until it is GC'ed.  This doesn't mean the
@@ -4800,7 +4804,7 @@ Thread::ApartmentState Thread::GetApartmentRare(Thread::ApartmentState as)
     }
     CONTRACTL_END;
 
-    if (this == GetThread())
+    if (this == GetThreadNULLOk())
     {
         THDTYPE type;
         HRESULT hr = S_OK;
@@ -5230,7 +5234,7 @@ void ThreadStore::AddThread(Thread *newThread, BOOL bRequiresTSL)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -5372,7 +5376,7 @@ void ThreadStore::TransferStartedThread(Thread *thread, BOOL bRequiresTSL)
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() == thread);
+    _ASSERTE(GetThreadNULLOk() == thread);
 
     LOG((LF_SYNC, INFO3, "TransferUnstartedThread obtain lock\n"));
     ThreadStoreLockHolder TSLockHolder(FALSE);
@@ -5791,7 +5795,7 @@ BOOL ThreadStore::DbgFindThread(Thread *target)
 
     // Cache the current change stamp for g_TrapReturningThreads
     LONG chgStamp = g_trtChgStamp;
-    STRESS_LOG3(LF_STORE, LL_INFO100, "ThreadStore::DbgFindThread - [thread=%p]. trt=%d. chgStamp=%d\n", GetThread(), g_TrapReturningThreads.Load(), chgStamp);
+    STRESS_LOG3(LF_STORE, LL_INFO100, "ThreadStore::DbgFindThread - [thread=%p]. trt=%d. chgStamp=%d\n", GetThreadNULLOk(), g_TrapReturningThreads.Load(), chgStamp);
 
 #if 0 // g_TrapReturningThreads debug code.
         int             iRetry = 0;
@@ -5864,7 +5868,7 @@ Retry:
     }
 #endif // g_TrapReturningThreads debug code.
 
-    STRESS_LOG4(LF_STORE, LL_INFO100, "ThreadStore::DbgFindThread - [thread=%p]. trt=%d. chg=%d. cnt=%d\n", GetThread(), g_TrapReturningThreads.Load(), g_trtChgStamp.Load(), cntReturn);
+    STRESS_LOG4(LF_STORE, LL_INFO100, "ThreadStore::DbgFindThread - [thread=%p]. trt=%d. chg=%d. cnt=%d\n", GetThreadNULLOk(), g_TrapReturningThreads.Load(), g_trtChgStamp.Load(), cntReturn);
 
     // Because of race conditions and the fact that the GC places its
     // own count, I can't assert this precisely.  But I do want to be
@@ -6281,8 +6285,8 @@ BOOL Thread::UniqueStack(void* stackStart)
     {
         CrstHolder ch(g_pUniqueStackCrst);
 #ifdef _DEBUG
-        if (GetThread ())
-            GetThread ()->m_bUniqueStacking = TRUE;
+        if (GetThreadNULLOk())
+            GetThread()->m_bUniqueStacking = TRUE;
 #endif
         if (g_pUniqueStackMap->LookupValue (stackTraceHash, stackTrace) != (LPVOID)INVALIDENTRY)
         {
@@ -6295,8 +6299,8 @@ BOOL Thread::UniqueStack(void* stackStart)
             UniqueStackHelper(stackTraceHash, stackTrace);
         }
 #ifdef _DEBUG
-        if (GetThread ())
-            GetThread ()->m_bUniqueStacking = FALSE;
+        if (GetThreadNULLOk())
+            GetThread()->m_bUniqueStacking = FALSE;
 #endif
     }
 
@@ -6668,7 +6672,7 @@ void Thread::DebugLogStackMBIs()
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();  // N.B. this can be NULL!
+    Thread* pThread = GetThreadNULLOk();  // N.B. this can be NULL!
 
     UINT_PTR uStackLimit        = (UINT_PTR)GetStackLowerBound();
     UINT_PTR uStackBase         = (UINT_PTR)GetStackUpperBound();
@@ -7028,7 +7032,7 @@ bool Thread::InitRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, bool validCo
 #else
             pctx->ContextFlags = CONTEXT_FULL;
 
-            _ASSERTE(this != GetThread());  // do not call GetThreadContext on the active thread
+            _ASSERTE(this != GetThreadNULLOk());  // do not call GetThreadContext on the active thread
 
             BOOL ret = EEGetThreadContext(this, pctx);
             if (!ret)
@@ -7103,7 +7107,6 @@ void CommonTripThread()
     CONTRACTL_END;
 
     Thread  *thread = GetThread();
-
     thread->HandleThreadAbort ();
 
     if (thread->CatchAtSafePoint())
@@ -7151,7 +7154,7 @@ void Thread::InitContext()
 {
     CONTRACTL {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -7165,7 +7168,7 @@ void Thread::ClearContext()
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -7416,7 +7419,6 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
 
     // Get the reference to the current thread..
     Thread *pCurThread = GetThread();
-    _ASSERTE(pCurThread);
 
     //
     // In the default domain, when an exception goes unhandled on a managed thread whose threadbase is in the VM (e.g. explicitly spawned threads,
@@ -7456,7 +7458,7 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
     STATIC_CONTRACT_MODE_COOPERATIVE;
 
     // HasStarted() must have already been performed by our caller
-    _ASSERTE(GetThread() != NULL);
+    _ASSERTE(GetThreadNULLOk() != NULL);
 
     Thread *pThread = GetThread();
 #ifdef FEATURE_EH_FUNCLETS
@@ -8094,9 +8096,6 @@ CHECK DeadlockAwareLock::CheckDeadlock(Thread *pThread)
 BOOL DeadlockAwareLock::CanEnterLock()
 {
     Thread * pThread = GetThread();
-
-    CONSISTENCY_CHECK_MSG(pThread != NULL,
-                          "Cannot do deadlock detection on non-EE thread");
     CONSISTENCY_CHECK_MSG(pThread->m_pBlockingLock.Load() == NULL,
                           "Cannot block on two locks at once");
 
@@ -8144,9 +8143,6 @@ BOOL DeadlockAwareLock::TryBeginEnterLock()
     CONTRACTL_END;
 
     Thread * pThread = GetThread();
-
-    CONSISTENCY_CHECK_MSG(pThread != NULL,
-                          "Cannot do deadlock detection on non-EE thread");
     CONSISTENCY_CHECK_MSG(pThread->m_pBlockingLock.Load() == NULL,
                           "Cannot block on two locks at once");
 
@@ -8196,9 +8192,6 @@ void DeadlockAwareLock::BeginEnterLock()
     CONTRACTL_END;
 
     Thread * pThread = GetThread();
-
-    CONSISTENCY_CHECK_MSG(pThread != NULL,
-                          "Cannot do deadlock detection on non-EE thread");
     CONSISTENCY_CHECK_MSG(pThread->m_pBlockingLock.Load() == NULL,
                           "Cannot block on two locks at once");
 
@@ -8295,7 +8288,7 @@ BOOL dbgOnly_IsSpecialEEThread()
     #endif
 
     //<TODO>Clean this up</TODO>
-    if (GetThread() == NULL)
+    if (GetThreadNULLOk() == NULL)
         return TRUE;
 
 
index 5be5ae9..94c9beb 100644 (file)
@@ -527,21 +527,6 @@ struct HijackArgs;
 
 #endif // FEATURE_HIJACK
 
-//***************************************************************************
-#ifdef ENABLE_CONTRACTS_IMPL
-inline Thread* GetThreadNULLOk()
-{
-    LIMITED_METHOD_CONTRACT;
-    Thread * pThread;
-    BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-    pThread = GetThread();
-    END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-    return pThread;
-}
-#else
-#define GetThreadNULLOk() GetThread()
-#endif
-
 // manifest constant for waiting in the exposed classlibs
 const INT32 INFINITE_TIMEOUT = -1;
 
@@ -634,6 +619,8 @@ EXTERN_C void WINAPI OnHijackFPTripThread();  // hijacked JIT code is returning
 
 void CommonTripThread();
 
+void SetupTLSForThread();
+
 // When we resume a thread at a new location, to get an exception thrown, we have to
 // pretend the exception originated elsewhere.
 EXTERN_C void ThrowControlForThread(
@@ -1042,8 +1029,6 @@ class Thread
 #endif // DACCESS_COMPILE
     friend class ProfToEEInterfaceImpl;     // HRESULT ProfToEEInterfaceImpl::GetHandleFromThread(ThreadID threadId, HANDLE *phThread);
 
-    friend void SetupTLSForThread(Thread* pThread);
-
     friend class CheckAsmOffsets;
 
     friend class ExceptionTracker;
@@ -3210,7 +3195,7 @@ public:
     static BOOL IsAddressInCurrentStack (PTR_VOID addr)
     {
         LIMITED_METHOD_DAC_CONTRACT;
-        Thread* currentThread = GetThread();
+        Thread* currentThread = GetThreadNULLOk();
         if (currentThread == NULL)
         {
             return FALSE;
@@ -4833,7 +4818,7 @@ public:
         WRAPPER_NO_CONTRACT;
         // Note that GetThread() may be 0 if it is the debugger thread
         // or perhaps a concurrent GC thread.
-        return HoldingThreadStore(GetThread());
+        return HoldingThreadStore(GetThreadNULLOk());
     }
 
     static BOOL HoldingThreadStore(Thread *pThread);
@@ -5247,13 +5232,9 @@ protected:
         if (m_WasCoop)
         {
             // m_WasCoop is only TRUE if we've already verified there's an EE thread.
-            BEGIN_GETTHREAD_ALLOWED;
-
             _ASSERTE(m_Thread != NULL);  // Cannot switch to cooperative with no thread
             if (!m_Thread->PreemptiveGCDisabled())
                 m_Thread->DisablePreemptiveGC();
-
-            END_GETTHREAD_ALLOWED;
         }
         else
         {
@@ -5267,10 +5248,8 @@ protected:
             // when it's TRUE, so we check it for perf.
             if (THREAD_EXISTS || m_Thread != NULL)
             {
-                BEGIN_GETTHREAD_ALLOWED;
                 if (m_Thread->PreemptiveGCDisabled())
                     m_Thread->EnablePreemptiveGC();
-                END_GETTHREAD_ALLOWED;
             }
         }
 
@@ -5303,7 +5282,6 @@ protected:
 
         if (m_Thread != NULL)
         {
-            BEGIN_GETTHREAD_ALLOWED;
             m_WasCoop = m_Thread->PreemptiveGCDisabled();
 
             if (conditional && !m_WasCoop)
@@ -5311,7 +5289,6 @@ protected:
                 m_Thread->DisablePreemptiveGC();
                 _ASSERTE(m_Thread->PreemptiveGCDisabled());
             }
-            END_GETTHREAD_ALLOWED;
         }
         else
         {
@@ -5330,15 +5307,12 @@ protected:
         m_fThreadMustExist = false;
         if (m_Thread != NULL && conditional)
         {
-            BEGIN_GETTHREAD_ALLOWED;
             GCHOLDER_CHECK_FOR_PREEMP_IN_NOTRIGGER(m_Thread);
-            END_GETTHREAD_ALLOWED;
         }
 #endif  // ENABLE_CONTRACTS_IMPL
 
         if (m_Thread != NULL)
         {
-            BEGIN_GETTHREAD_ALLOWED;
             m_WasCoop = m_Thread->PreemptiveGCDisabled();
 
             if (conditional && m_WasCoop)
@@ -5346,7 +5320,6 @@ protected:
                 m_Thread->EnablePreemptiveGC();
                 _ASSERTE(!m_Thread->PreemptiveGCDisabled());
             }
-            END_GETTHREAD_ALLOWED;
         }
         else
         {
@@ -5359,7 +5332,7 @@ protected:
     {
         // This is the perf version. So we deliberately restrict the calls
         // to already setup threads to avoid the null checks and GetThread call
-        _ASSERTE(pThread && (pThread == GetThread()));
+        _ASSERTE(pThread == GetThread());
 #ifdef ENABLE_CONTRACTS_IMPL
         m_fThreadMustExist = true;
 #endif // ENABLE_CONTRACTS_IMPL
@@ -5381,7 +5354,7 @@ protected:
     {
         // This is the perf version. So we deliberately restrict the calls
         // to already setup threads to avoid the null checks and GetThread call
-        _ASSERTE(!THREAD_EXISTS || (pThread && (pThread == GetThread())));
+        _ASSERTE(!THREAD_EXISTS || (pThread == GetThread()));
 #ifdef ENABLE_CONTRACTS_IMPL
         m_fThreadMustExist = !!THREAD_EXISTS;
 #endif // ENABLE_CONTRACTS_IMPL
@@ -5695,7 +5668,7 @@ public:
     FORCEINLINE void DoCheck()
     {
         WRAPPER_NO_CONTRACT;
-        Thread *pThread = GetThread();
+        Thread *pThread = GetThreadNULLOk();
         if (COOPERATIVE)
         {
             _ASSERTE(pThread != NULL);
@@ -6006,7 +5979,7 @@ public:
 inline BOOL GC_ON_TRANSITIONS(BOOL val) {
     WRAPPER_NO_CONTRACT;
 #ifdef _DEBUG
-    Thread* thread = GetThread();
+    Thread* thread = GetThreadNULLOk();
     if (thread == 0)
         return(FALSE);
     BOOL ret = thread->m_GCOnTransitionsOK;
@@ -6200,7 +6173,6 @@ class DeadlockAwareLock
     static void ReleaseBlockingLock()
     {
         Thread *pThread = GetThread();
-        _ASSERTE (pThread);
         pThread->m_pBlockingLock = NULL;
     }
 public:
@@ -6237,7 +6209,7 @@ public:
     ThreadStateHolder (BOOL fNeed, DWORD state)
     {
         LIMITED_METHOD_CONTRACT;
-        _ASSERTE (GetThread());
+        _ASSERTE (GetThreadNULLOk());
         m_fNeed = fNeed;
         m_state = state;
     }
@@ -6248,7 +6220,6 @@ public:
         if (m_fNeed)
         {
             Thread *pThread = GetThread();
-            _ASSERTE (pThread);
             FastInterlockAnd((ULONG *) &pThread->m_State, ~m_state);
         }
     }
@@ -6271,15 +6242,13 @@ class ThreadStateNCStackHolder
     {
         LIMITED_METHOD_CONTRACT;
 
-        _ASSERTE (GetThread());
+        _ASSERTE (GetThreadNULLOk());
         m_fNeed = fNeed;
         m_state = state;
 
         if (fNeed)
         {
             Thread *pThread = GetThread();
-            _ASSERTE (pThread);
-
             if (fNeed < 0)
             {
                 // if the state is set, reset it
@@ -6315,8 +6284,6 @@ class ThreadStateNCStackHolder
         if (m_fNeed)
         {
             Thread *pThread = GetThread();
-            _ASSERTE (pThread);
-
             if (m_fNeed < 0)
             {
                 pThread->SetThreadStateNC(m_state); // set it
index 5dc6ef8..e6b0595 100644 (file)
@@ -32,11 +32,18 @@ __declspec(selectany) __declspec(thread) ThreadLocalInfo gCurrentThreadInfo;
 EXTERN_C __thread ThreadLocalInfo gCurrentThreadInfo;
 #endif
 
-EXTERN_C inline Thread* STDCALL GetThread()
+inline Thread* GetThreadNULLOk()
 {
     return gCurrentThreadInfo.m_pThread;
 }
 
+inline Thread* GetThread()
+{
+    Thread* pThread = gCurrentThreadInfo.m_pThread;
+    _ASSERTE(pThread);
+    return pThread;
+}
+
 EXTERN_C inline AppDomain* STDCALL GetAppDomain()
 {
     return AppDomain::GetCurrentDomain();
@@ -173,7 +180,6 @@ inline Thread::CurrentPrepareCodeConfigHolder::CurrentPrepareCodeConfigHolder(Th
 #endif
 {
     LIMITED_METHOD_CONTRACT;
-    _ASSERTE(thread != nullptr);
     _ASSERTE(thread == GetThread());
     _ASSERTE(config != nullptr);
 
index 14d909f..1755bf7 100644 (file)
@@ -536,7 +536,6 @@ class ThreadStatics
     {
         // Get the current thread
         Thread * pThread = GetThread();
-
         return &pThread->m_ThreadLocalBlock;
     }
 
index 6514bf8..1f4fd81 100644 (file)
@@ -331,7 +331,7 @@ Thread::SuspendThreadResult Thread::SuspendThread(BOOL fOneTryOnly, DWORD *pdwSu
             }
             // We suspend the right thread
 #ifdef _DEBUG
-            Thread * pCurThread = GetThread();
+            Thread * pCurThread = GetThreadNULLOk();
             if (pCurThread != NULL)
             {
                 pCurThread->dbg_m_cSuspendedThreads ++;
@@ -445,7 +445,7 @@ DWORD Thread::ResumeThread()
     _ASSERTE (!m_Creater.IsCurrentThread());
     if ((res != (DWORD)-1) && (res != 0))
     {
-        Thread * pCurThread = GetThread();
+        Thread * pCurThread = GetThreadNULLOk();
         if (pCurThread != NULL)
         {
             _ASSERTE(pCurThread->dbg_m_cSuspendedThreads > 0);
@@ -496,7 +496,7 @@ static inline BOOL CheckSuspended(Thread *pThread)
     }
     CONTRACTL_END;
 
-    _ASSERTE(GetThread() != pThread);
+    _ASSERTE(GetThreadNULLOk() != pThread);
     _ASSERTE(CheckPointer(pThread));
 
 #ifndef DISABLE_THREADSUSPEND
@@ -684,7 +684,7 @@ static StackWalkAction TAStackCrawlCallBackWorker(CrawlFrame* pCf, StackCrawlCon
         // !!! is to check if the target thread is processing exception.
         // !!! If exception is in flight, we don't induce ThreadAbort.  Instead at the end of Jit_EndCatch
         // !!! we will handle abort.
-        if (pData->pAbortee != GetThread() && !IsFaultOrFinally(&EHClause))
+        if (pData->pAbortee != GetThreadNULLOk() && !IsFaultOrFinally(&EHClause))
         {
             continue;
         }
@@ -876,7 +876,6 @@ BOOL Thread::IsExecutingWithinCer()
         return FALSE;
 
     Thread *pThread = GetThread();
-    _ASSERTE (pThread);
     StackCrawlContext sContext = { pThread,
                                    StackCrawlContext::SCC_CheckWithinCer,
         FALSE,
@@ -965,7 +964,7 @@ BOOL Thread::ReadyForAsyncException()
         return FALSE;
     }
 
-    if (GetThread() == this && HasThreadStateNC (TSNC_PreparingAbort) && !IsRudeAbort() )
+    if (GetThreadNULLOk() == this && HasThreadStateNC (TSNC_PreparingAbort) && !IsRudeAbort() )
     {
         STRESS_LOG0(LF_APPDOMAIN, LL_INFO10, "in Thread::ReadyForAbort  PreparingAbort\n");
         // Avoid recursive call
@@ -1055,7 +1054,7 @@ BOOL Thread::ReadyForAsyncException()
 
     StackWalkFramesEx(&rd, TAStackCrawlCallBack, &TAContext, QUICKUNWIND, pStartFrame);
 
-    _ASSERTE(TAContext.fHasManagedCodeOnStack || !IsAbortInitiated() || (GetThread() != this));
+    _ASSERTE(TAContext.fHasManagedCodeOnStack || !IsAbortInitiated() || (GetThreadNULLOk() != this));
 
     if (TAContext.fWithinCer)
     {
@@ -1193,7 +1192,7 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout)
     CONTRACTL
     {
         THROWS;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -1214,7 +1213,7 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout)
 
     MarkThreadForAbort(abortType);
 
-    Thread *pCurThread = GetThread();
+    Thread *pCurThread = GetThreadNULLOk();
 
     // If aborting self
     if (this == pCurThread)
@@ -1840,7 +1839,7 @@ void ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_REASON reason)
     CONTRACTL {
         NOTHROW;
     // any thread entering with `PreemptiveGCDisabled` should be prepared to switch mode, thus GC_TRIGGERS
-        if ((GetThread() != NULL) && GetThread()->PreemptiveGCDisabled()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if ((GetThreadNULLOk() != NULL) && GetThread()->PreemptiveGCDisabled()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -1853,7 +1852,7 @@ void ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_REASON reason)
     {
         BOOL gcOnTransitions;
 
-        Thread *pCurThread = GetThread();
+        Thread *pCurThread = GetThreadNULLOk();
 
         gcOnTransitions = GC_ON_TRANSITIONS(FALSE);                // dont do GC for GCStress 3
 
@@ -1934,14 +1933,14 @@ void ThreadSuspend::UnlockThreadStore(BOOL bThreadDestroyed, ThreadSuspend::SUSP
     // 10 of our COM BVTs.
     if (!IsAtProcessExit())
     {
-        Thread *pCurThread = GetThread();
+        Thread *pCurThread = GetThreadNULLOk();
 
         LOG((LF_SYNC, INFO3, "Unlocking thread store\n"));
-        _ASSERTE(GetThread() == NULL || ThreadStore::s_pThreadStore->m_HoldingThread == GetThread());
+        _ASSERTE(pCurThread == NULL || ThreadStore::s_pThreadStore->m_HoldingThread == pCurThread);
 
 #ifdef _DEBUG
         // If Thread object has been destroyed, we need to reset the ownership info in Crst.
-        _ASSERTE(!bThreadDestroyed || GetThread() == NULL);
+        _ASSERTE(!bThreadDestroyed || pCurThread == NULL);
         if (bThreadDestroyed) {
             ThreadStore::s_pThreadStore->m_Crst.m_holderthreadid.SetToCurrentThread();
         }
@@ -2556,8 +2555,6 @@ int RedirectedHandledJITCaseExceptionFilter(
 
     // Get the thread handle
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
 
     STRESS_LOG2(LF_SYNC, LL_INFO100, "In RedirectedHandledJITCaseExceptionFilter fDone = %d pFrame = %p\n", fDone, pFrame);
 
@@ -2668,7 +2665,6 @@ void __stdcall Thread::RedirectedHandledJITCase(RedirectReason reason)
     DWORD dwLastError = GetLastError(); // BEGIN_PRESERVE_LAST_ERROR
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
 
     // Get the saved context
     CONTEXT *pCtx = pThread->GetSavedRedirectContext();
@@ -2900,7 +2896,7 @@ BOOL Thread::RedirectThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt)
     CONTRACTL_END;
 
     _ASSERTE(HandledJITCase());
-    _ASSERTE(GetThread() != this);
+    _ASSERTE(GetThreadNULLOk() != this);
     _ASSERTE(ThreadStore::HoldingThreadStore());
 
     ////////////////////////////////////////////////////////////////
@@ -2997,7 +2993,7 @@ BOOL Thread::CheckForAndDoRedirect(PFN_REDIRECTTARGET pRedirectTarget)
     }
     CONTRACTL_END;
 
-    _ASSERTE(this != GetThread());
+    _ASSERTE(this != GetThreadNULLOk());
     _ASSERTE(PreemptiveGCDisabledOther());
     _ASSERTE(IsAddrOfRedirectFunc(pRedirectTarget));
 
@@ -3231,7 +3227,7 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread())
+        if (GetThreadNULLOk())
         {
             GC_TRIGGERS;            // CLREvent::Wait is GC_TRIGGERS
         }
@@ -3243,7 +3239,7 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
     CONTRACTL_END;
 
     // This thread
-    Thread  *pCurThread = GetThread();
+    Thread  *pCurThread = GetThreadNULLOk();
 
     // Caller is expected to be holding the ThreadStore lock.  Also, caller must
     // have set GcInProgress before coming here, or things will break;
@@ -3743,11 +3739,11 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded)
 {
     CONTRACTL {
         NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
-    Thread  *pCurThread = GetThread();
+    Thread  *pCurThread = GetThreadNULLOk();
 
     // Caller is expected to be holding the ThreadStore lock.  But they must have
     // reset GcInProgress, or threads will continue to suspend themselves and won't
@@ -3839,8 +3835,6 @@ int RedirectedThrowControlExceptionFilter(
 
     // Get the thread handle
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
-
 
     STRESS_LOG0(LF_SYNC, LL_INFO100, "In RedirectedThrowControlExceptionFilter\n");
 
@@ -3897,7 +3891,6 @@ ThrowControlForThread(
     STATIC_CONTRACT_GC_NOTRIGGER;
 
     Thread *pThread = GetThread();
-    _ASSERTE(pThread);
     _ASSERTE(pThread->m_OSContext);
 
     _ASSERTE(pThread->PreemptiveGCDisabled());
@@ -4110,7 +4103,7 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain)
     }
     CONTRACTL_END;
 
-    Thread  *pCurThread = GetThread();
+    Thread  *pCurThread = GetThreadNULLOk();
     Thread  *thread = NULL;
 
     if (IsAtProcessExit())
@@ -4322,7 +4315,7 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync)
         // We assume that only the "real" helper thread ever calls this (not somebody doing helper thread duty).
         PRECONDITION(ThreadStore::HoldingThreadStore());
         PRECONDITION(IsDbgHelperSpecialThread());
-        PRECONDITION(GetThread() == NULL);
+        PRECONDITION(GetThreadNULLOk() == NULL);
 
         // Iff we return true, then we have the TSL (or the aux lock used in workarounds).
         POSTCONDITION(ThreadStore::HoldingThreadStore());
@@ -5383,7 +5376,7 @@ BOOL Thread::HandledJITCase()
 
 #ifdef _DEBUG
     // We know IP is in managed code, mark current thread as safe for calls into host
-    Thread * pCurThread = GetThread();
+    Thread * pCurThread = GetThreadNULLOk();
     if (pCurThread != NULL)
     {
         pCurThread->dbg_m_cSuspendedThreadsWithoutOSLock ++;
@@ -5632,7 +5625,7 @@ void ThreadSuspend::SuspendEE(SUSPEND_REASON reason)
 
     gcOnTransitions = GC_ON_TRANSITIONS(FALSE);        // dont do GC for GCStress 3
 
-    Thread* pCurThread = GetThread();
+    Thread* pCurThread = GetThreadNULLOk();
 
     DWORD dwSwitchCount = 0;
 
@@ -5869,7 +5862,7 @@ retry_for_debugger:
 // is in a function where we can safely inject activation.
 BOOL CheckActivationSafePoint(SIZE_T ip, BOOL checkingCurrentThread)
 {
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     // It is safe to call the ExecutionManager::IsManagedCode only if we are making the check for
     // a thread different from the current one or if the current thread is in the cooperative mode.
     // Otherwise ExecutionManager::IsManagedCode could deadlock if the activation happened when the
@@ -6017,7 +6010,7 @@ BOOL Debug_IsLockedViaThreadSuspension()
     return GCHeapUtilities::IsGCInProgress() &&
                     (dbgOnly_IsSpecialEEThread() ||
                     IsGCSpecialThread() ||
-                    GetThread() == ThreadSuspend::GetSuspensionThread());
+                    GetThreadNULLOk() == ThreadSuspend::GetSuspensionThread());
 }
 #endif
 
index 9cfe20d..64130d6 100644 (file)
@@ -2098,7 +2098,7 @@ int GetRandomInt(int maxVal)
 {
 #ifndef CROSSGEN_COMPILE
     // Use the thread-local Random instance if possible
-    Thread* pThread = GetThread();
+    Thread* pThread = GetThreadNULLOk();
     if (pThread)
         return pThread->GetRandom()->Next(maxVal);
 #endif
index f0aa1db..878e672 100644 (file)
@@ -4011,8 +4011,7 @@ VirtualCallStubManager *VirtualCallStubManagerManager::FindVirtualCallStubManage
 
     // Check the current and shared domains.
     {
-        Thread *pThread = GetThread();
-
+        Thread *pThread = GetThreadNULLOk();
         if (pThread != NULL)
         {
             // Check the current domain
index 48e5253..4619c74 100644 (file)
@@ -790,7 +790,7 @@ void QueueUserWorkItemHelp(LPTHREAD_START_ROUTINE Function, PVOID Context)
 
     Function(Context);
 
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread)
     {
         _ASSERTE(!pThread->IsAbortRequested());
@@ -990,7 +990,7 @@ void ThreadpoolMgr::AdjustMaxWorkersActive()
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
     }
     CONTRACTL_END;
@@ -1075,7 +1075,7 @@ void ThreadpoolMgr::MaybeAddWorkingWorker()
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
     }
     CONTRACTL_END;
@@ -1232,7 +1232,7 @@ void WINAPI ThreadpoolMgr::ManagedWaitIOCompletionCallback(
     DWORD dwNumberOfBytesTransfered,
     LPOVERLAPPED lpOverlapped)
 {
-    Thread *pThread = GetThread();
+    Thread *pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         ClrFlsSetThreadType(ThreadType_Threadpool_Worker);
@@ -1535,8 +1535,6 @@ BOOL ThreadpoolMgr::SetAppDomainRequestsActive(BOOL UnmanagedTP)
     else
     {
         Thread* pCurThread = GetThread();
-        _ASSERTE( pCurThread);
-
         AppDomain* pAppDomain = pCurThread->GetDomain();
         _ASSERTE(pAppDomain);
 
@@ -1586,8 +1584,6 @@ void ThreadpoolMgr::ClearAppDomainRequestsActive(BOOL UnmanagedTP, LONG id)
     else
     {
        Thread* pCurThread = GetThread();
-       _ASSERTE( pCurThread);
-
        AppDomain* pAppDomain = pCurThread->GetDomain();
        _ASSERTE(pAppDomain);
 
@@ -1688,7 +1684,7 @@ void ThreadpoolMgr::RecycleMemory(LPVOID mem, enum MemType memType)
 Thread* ThreadpoolMgr::CreateUnimpersonatedThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpArgs, BOOL *pIsCLRThread)
 {
     STATIC_CONTRACT_NOTHROW;
-    if (GetThread()) { STATIC_CONTRACT_GC_TRIGGERS;} else {DISABLED(STATIC_CONTRACT_GC_NOTRIGGER);}
+    if (GetThreadNULLOk()) { STATIC_CONTRACT_GC_TRIGGERS;} else {DISABLED(STATIC_CONTRACT_GC_NOTRIGGER);}
     STATIC_CONTRACT_MODE_ANY;
     /* cannot use contract because of SEH
     CONTRACTL
@@ -1770,7 +1766,7 @@ BOOL ThreadpoolMgr::CreateWorkerThread()
 {
     CONTRACTL
     {
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         NOTHROW;
         MODE_ANY;   // We may try to add a worker thread while queuing a work item thru an fcall
     }
@@ -1935,7 +1931,7 @@ Work:
     {
         // Reset TLS etc. for next WorkRequest.
         if (pThread == NULL)
-            pThread = GetThread();
+            pThread = GetThreadNULLOk();
 
         if (pThread)
         {
@@ -2164,7 +2160,7 @@ BOOL ThreadpoolMgr::RegisterWaitForSingleObject(PHANDLE phNewWaitObject,
     {
         THROWS;
         MODE_ANY;
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -2744,8 +2740,7 @@ DWORD WINAPI ThreadpoolMgr::AsyncCallbackCompletion(PVOID pArgs)
     }
     CONTRACTL_END;
 
-    Thread * pThread = GetThread();
-
+    Thread * pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         HRESULT hr = ERROR_SUCCESS;
@@ -2860,7 +2855,7 @@ void ThreadpoolMgr::DeleteWait(WaitInfo* waitInfo)
     {
         if (waitInfo->ExternalEventSafeHandle != NULL) { THROWS;} else { NOTHROW; }
         MODE_ANY;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -2905,7 +2900,7 @@ BOOL ThreadpoolMgr::UnregisterWaitEx(HANDLE hWaitObject,HANDLE Event)
     CONTRACTL
     {
         THROWS; //NOTHROW;
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
     }
     CONTRACTL_END;
@@ -3070,7 +3065,7 @@ BOOL ThreadpoolMgr::BindIoCompletionCallback(HANDLE FileHandle,
     CONTRACTL
     {
         THROWS;     // EnsureInitialized can throw
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
     }
     CONTRACTL_END;
@@ -3114,7 +3109,7 @@ BOOL ThreadpoolMgr::CreateCompletionPortThread(LPVOID lpArgs)
     CONTRACTL
     {
         NOTHROW;
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         MODE_ANY;
     }
     CONTRACTL_END;
@@ -3153,8 +3148,8 @@ DWORD WINAPI ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
     CONTRACTL
     {
         THROWS;
-        if (GetThread()) { MODE_PREEMPTIVE;} else { DISABLED(MODE_ANY);}
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { MODE_PREEMPTIVE;} else { DISABLED(MODE_ANY);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
     }
     CONTRACTL_END;
 
@@ -3268,12 +3263,11 @@ Top:
 
             if (pThread == NULL)
             {
-                pThread = GetThread();
+                pThread = GetThreadNULLOk();
             }
 
             if (pThread)
             {
-
                 context = (PIOCompletionContext) pThread->GetIOCompletionContext();
 
                 if (context->lpOverlapped != NULL)
@@ -3510,7 +3504,7 @@ Top:
 
                 if (pThread == NULL)
                 {
-                    pThread = GetThread();
+                    pThread = GetThreadNULLOk();
                 }
 
                 if (pThread)
@@ -3713,7 +3707,7 @@ void ThreadpoolMgr::GrowCompletionPortThreadpoolIfNeeded()
 {
     CONTRACTL
     {
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
         NOTHROW;
         MODE_ANY;
     }
@@ -4326,7 +4320,7 @@ BOOL ThreadpoolMgr::CreateTimerQueueTimer(PHANDLE phNewTimer,
     CONTRACTL
     {
         THROWS;     // EnsureInitialized, CreateAutoEvent can throw
-        if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}  // There can be calls thru ICorThreadpool
+        if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}  // There can be calls thru ICorThreadpool
         MODE_ANY;
         INJECT_FAULT(COMPlusThrowOM());
     }
@@ -4561,8 +4555,8 @@ DWORD ThreadpoolMgr::FireTimers()
     CONTRACTL
     {
         THROWS;     // QueueUserWorkItem can throw
-        if (GetThread()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
-        if (GetThread()) { MODE_PREEMPTIVE;} else { DISABLED(MODE_ANY);}
+        if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+        if (GetThreadNULLOk()) { MODE_PREEMPTIVE;} else { DISABLED(MODE_ANY);}
     }
     CONTRACTL_END;
 
@@ -4662,8 +4656,7 @@ DWORD WINAPI ThreadpoolMgr::AsyncTimerCallbackCompletion(PVOID pArgs)
     }
     CONTRACTL_END;
 
-    Thread* pThread = GetThread();
-
+    Thread* pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         HRESULT hr = ERROR_SUCCESS;
@@ -4715,8 +4708,7 @@ DWORD WINAPI ThreadpoolMgr::AsyncDeleteTimer(PVOID pArgs)
     }
     CONTRACTL_END;
 
-    Thread * pThread = GetThread();
-
+    Thread * pThread = GetThreadNULLOk();
     if (pThread == NULL)
     {
         HRESULT hr = ERROR_SUCCESS;
@@ -4739,7 +4731,7 @@ void ThreadpoolMgr::DeleteTimer(TimerInfo* timerInfo)
 {
     CONTRACTL
     {
-        if (GetThread() == pTimerThread) { NOTHROW; } else { THROWS; }
+        if (GetThreadNULLOk() == pTimerThread) { NOTHROW; } else { THROWS; }
         GC_TRIGGERS;
         MODE_ANY;
     }
@@ -4767,7 +4759,7 @@ void ThreadpoolMgr::DeleteTimer(TimerInfo* timerInfo)
     }
 
     // We cannot block the timer thread, so some cleanup is deferred to other threads.
-    if (GetThread() == pTimerThread)
+    if (GetThreadNULLOk() == pTimerThread)
     {
         // Notify the ExternalEventSafeHandle with an user work item
         if (timerInfo->ExternalEventSafeHandle != NULL)
@@ -4842,7 +4834,6 @@ void ThreadpoolMgr::QueueTimerInfoForRelease(TimerInfo *pTimerInfo)
     //  - This function wont go into an alertable state. That could trigger another APC.
     // Else two threads can be queueing timerinfos and a race could
     // lead to leaked memory and handles
-    _ASSERTE(GetThread());
     _ASSERTE(pTimerThread == GetThread());
     TimerInfo *pHead = NULL;
 
@@ -5045,7 +5036,7 @@ BOOL ThreadpoolMgr::DeleteTimerQueueTimer(
     {
         _ASSERTE(timerInfo->ExternalEventSafeHandle == NULL);
         _ASSERTE(timerInfo->ExternalCompletionEvent == INVALID_HANDLE);
-        _ASSERTE(GetThread() != pTimerThread);
+        _ASSERTE(GetThreadNULLOk() != pTimerThread);
 
         timerInfo->InternalCompletionEvent.Wait(INFINITE,TRUE /*alertable*/);
         timerInfo->InternalCompletionEvent.CloseEvent();
index 551cc4d..f064ec7 100644 (file)
@@ -859,7 +859,7 @@ public:
         WRAPPER_NO_CONTRACT;
         _ASSERTE(!UsePortableThreadPool());
 
-        Thread::IncrementWorkerThreadPoolCompletionCount(GetThread());
+        Thread::IncrementWorkerThreadPoolCompletionCount(GetThreadNULLOk());
         UpdateLastDequeueTime();
     }