Fix ReJIT failures (#25377)
authorDavid Mason <davmason@microsoft.com>
Wed, 26 Jun 2019 03:15:02 +0000 (20:15 -0700)
committerGitHub <noreply@github.com>
Wed, 26 Jun 2019 03:15:02 +0000 (20:15 -0700)
src/inc/profilepriv.h
src/vm/codeversion.cpp
src/vm/proftoeeinterfaceimpl.cpp
src/vm/proftoeeinterfaceimpl.h
src/vm/proftoeeinterfaceimpl.inl

index a5e2398..91791f5 100644 (file)
@@ -146,6 +146,7 @@ GVAL_DECL(ProfControlBlock, g_profControlBlock);
 #define COR_PRF_CALLBACKSTATE_INCALLBACK                 0x1
 #define COR_PRF_CALLBACKSTATE_IN_TRIGGERS_SCOPE          0x2
 #define COR_PRF_CALLBACKSTATE_FORCEGC_WAS_CALLED         0x4
+#define COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED           0x8
 //
 //---------------------------------------------------------------
 
index 6d7cbe8..c90189b 100644 (file)
@@ -2348,6 +2348,7 @@ HRESULT CodeVersionManager::PublishNativeCodeVersion(MethodDesc* pMethod, Native
         {
             MODE_ANY;
         }
+        NOTHROW;
     }
     CONTRACTL_END;
 
index f238723..cff1721 100644 (file)
@@ -6805,6 +6805,12 @@ HRESULT ProfToEEInterfaceImpl::RequestReJITWithInliners(
 
     // Remember the profiler is doing this, as that means we must never detach it!
     g_profControlBlock.pProfInterface->SetUnrevertiblyModifiedILFlag();
+
+    HRESULT hr = SetupThreadForReJIT();
+    if (FAILED(hr))
+    {
+        return hr;
+    }
     
     GCX_PREEMP();
     return ReJitManager::RequestReJIT(cFunctions, moduleIds, methodIds, static_cast<COR_PRF_REJIT_FLAGS>(dwRejitFlags));
@@ -8655,6 +8661,27 @@ HRESULT ProfToEEInterfaceImpl::GetReJITIDs(
     return ReJitManager::GetReJITIDs(pMD, cReJitIds, pcReJitIds, reJitIds);
 }
 
+
+HRESULT ProfToEEInterfaceImpl::SetupThreadForReJIT()
+{
+    LIMITED_METHOD_CONTRACT;
+
+    HRESULT hr = S_OK;
+    EX_TRY
+    {
+        if (GetThread() == NULL)
+        {
+            SetupThread();
+        }
+
+        Thread *pThread = GetThread();
+        pThread->SetProfilerCallbackStateFlags(COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED);
+    }
+    EX_CATCH_HRESULT(hr);
+
+    return hr;
+}
+
 HRESULT ProfToEEInterfaceImpl::RequestReJIT(ULONG       cFunctions,   // in
                                             ModuleID    moduleIds[],  // in
                                             mdMethodDef methodIds[])  // in
@@ -8704,6 +8731,12 @@ HRESULT ProfToEEInterfaceImpl::RequestReJIT(ULONG       cFunctions,   // in
     // Remember the profiler is doing this, as that means we must never detach it!
     g_profControlBlock.pProfInterface->SetUnrevertiblyModifiedILFlag();
     
+    HRESULT hr = SetupThreadForReJIT();
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+    
     GCX_PREEMP();
     return ReJitManager::RequestReJIT(cFunctions, moduleIds, methodIds, static_cast<COR_PRF_REJIT_FLAGS>(0));
 }
@@ -8761,6 +8794,12 @@ HRESULT ProfToEEInterfaceImpl::RequestRevert(ULONG       cFunctions,  // in
         memset(rgHrStatuses, 0, sizeof(HRESULT) * cFunctions);
         _ASSERTE(S_OK == rgHrStatuses[0]);
     }
+    
+    HRESULT hr = SetupThreadForReJIT();
+    if (FAILED(hr))
+    {
+        return hr;
+    }
 
     GCX_PREEMP();
     return ReJitManager::RequestRevert(cFunctions, moduleIds, methodIds, rgHrStatuses);
index 335b4f7..bc4b13d 100644 (file)
@@ -659,6 +659,8 @@ protected:
 
     HRESULT EnumJITedFunctionsHelper(ProfilerFunctionEnum ** ppEnum, IJitManager ** ppJitMgr);
 
+    HRESULT SetupThreadForReJIT();
+
 #ifdef _TARGET_X86_
     HRESULT ProfilerEbpWalker(Thread * pThreadToSnapshot, LPCONTEXT pctxSeed, StackSnapshotCallback * callback, void * clientData);
 #endif //_TARGET_X86_
index 58a3770..6652585 100644 (file)
@@ -63,9 +63,10 @@ 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)
+    if (((dwProfilerCallbackFullStateFlags & COR_PRF_CALLBACKSTATE_FORCEGC_WAS_CALLED) != 0)
+        || ((dwProfilerCallbackFullStateFlags & COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED) != 0))
     {
-        // Threads on which ForceGC() was successfully called should be treated just
+        // Threads on which ForceGC() or RequestReJIT() was successfully called should be treated just
         // like native threads.  Profiler can do whatever it wants
         return TRUE;
     }