Harden test against JIT optimizations
authorJoseph Tremoulet <jotrem@microsoft.com>
Tue, 13 Sep 2016 17:01:15 +0000 (13:01 -0400)
committerJoseph Tremoulet <jotrem@microsoft.com>
Thu, 15 Sep 2016 15:40:52 +0000 (11:40 -0400)
Declare static field `finalizerCompletedOnce` volatile -- this test has a
side-effect-free busy-loop which checks that static variable for a change it
expects a finalizer to make to it; this static field must be volatile to
ensure the jit doesn't hoist the load from the loop.

Call GC.KeepAlive on the objects constructed in the various allocation
loops in this test, to make sure that the entire allocation isn't
optimized away.

Commit migrated from https://github.com/dotnet/coreclr/commit/f6b070c69585761996778fa5228b07d0be26be57

src/coreclr/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs

index 0fda817..60a6861 100644 (file)
@@ -17,6 +17,7 @@ public class FinalizeTimeout
         do
         {
             finalizableObject = new BlockingFinalizerOnShutdown();
+            GC.KeepAlive(finalizableObject);
         } while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce);
 
         // Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the
@@ -42,12 +43,15 @@ public class FinalizeTimeout
     {
         byte[] b;
         while (true)
+        {
             b = new byte[1024];
+            GC.KeepAlive(b);
+        }
     }
 
     private class BlockingFinalizerOnShutdown
     {
-        public static bool finalizerCompletedOnce = false;
+        public volatile static bool finalizerCompletedOnce = false;
         public bool isLastObject = false;
 
         ~BlockingFinalizerOnShutdown()
@@ -68,6 +72,7 @@ public class FinalizeTimeout
             do
             {
                 o = new object();
+                GC.KeepAlive(o);
             } while ((++i & 0xff) != 0 || (elapsed = DateTime.Now - start) < timeout);
 
             Console.WriteLine("Finalizer end");