VS2015 optimizer is smart enough to optimize out stores into globals that are only read by the DAC.
// 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.
#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>
// 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;