Use volatile stores for values read by DAC
authorJan Kotas <jkotas@microsoft.com>
Thu, 20 Aug 2015 06:50:32 +0000 (23:50 -0700)
committerJan Kotas <jkotas@microsoft.com>
Fri, 21 Aug 2015 03:27:55 +0000 (20:27 -0700)
VS2015 optimizer is smart enough to optimize out stores into globals that are only read by the DAC.

src/debug/ee/debugger.cpp
src/inc/volatile.h
src/vm/win32threadpool.cpp

index ce72f27..330a4b3 100644 (file)
@@ -2195,7 +2195,8 @@ HRESULT Debugger::StartupPhase2(Thread * pThread)
 
     // After returning from debugger startup we assume that the runtime might start using the NGEN flags to make
     // binding decisions. From now on the debugger can not influence NGEN binding policy
-    s_fCanChangeNgenFlags = FALSE;
+    // Use volatile store to guarantee make the value visible to the DAC (the store can be optimized out otherwise)
+    VolatileStoreWithoutBarrier(&s_fCanChangeNgenFlags, FALSE);
 
     // Must release the lock (which would be done at the end of this method anyways) so that
     // the helper thread can do the jit-attach.
index 8ec4296..c151a76 100644 (file)
@@ -176,6 +176,19 @@ void VolatileStore(T* pt, T val)
 #endif
 }
 
+template<typename T>
+inline
+void VolatileStoreWithoutBarrier(T* pt, T val)
+{
+    STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY;
+
+#ifndef DACCESS_COMPILE
+    *(T volatile *)pt = val;
+#else
+    *pt = val;
+#endif
+}
+
 //
 // Volatile<T> implements accesses with our volatile semantics over a variable of type T.
 // Wherever you would have used a "volatile Foo" or, equivalently, "Foo volatile", use Volatile<Foo> 
index 3e80eb1..a13e905 100644 (file)
@@ -414,7 +414,8 @@ BOOL ThreadpoolMgr::Initialize()
     // initialize CP thread settings
     MinLimitTotalCPThreads = NumberOfProcessors;
 
-    MaxFreeCPThreads = NumberOfProcessors*MaxFreeCPThreadsPerCPU;
+    // Use volatile store to guarantee make the value visible to the DAC (the store can be optimized out otherwise)
+    VolatileStoreWithoutBarrier<LONG>(&MaxFreeCPThreads, NumberOfProcessors*MaxFreeCPThreadsPerCPU);
 
     counts.NumActive = 0;
     counts.NumWorking = 0;