Fix an issue where GCStress allocated objects using the Gen 0 alloc context (dotnet...
authorSean Gillespie <sean@swgillespie.me>
Wed, 22 Mar 2017 17:25:08 +0000 (10:25 -0700)
committerGitHub <noreply@github.com>
Wed, 22 Mar 2017 17:25:08 +0000 (10:25 -0700)
* Fix an issue where GCStress allocated objects using the Gen 0 alloc context

* Remove a GCStress MaybeTrigger on LOH allocations that attempted to use the gen 0 alloc context

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

src/coreclr/src/gc/gc.cpp
src/coreclr/src/gc/gcinterface.h
src/coreclr/src/vm/gccover.cpp
src/coreclr/src/vm/gcstress.h
src/coreclr/src/vm/threadsuspend.cpp

index b58f4cc..a217563 100644 (file)
@@ -34101,6 +34101,7 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
 {
 #if defined(STRESS_HEAP) && !defined(FEATURE_REDHAWK)
     alloc_context* acontext = static_cast<alloc_context*>(context);
+    assert(context != nullptr);
 
     // if GC stress was dynamically disabled during this run we return FALSE
     if (!GCStressPolicy::IsEnabled())
@@ -34182,9 +34183,6 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
 #ifndef MULTIPLE_HEAPS
     static int32_t OneAtATime = -1;
 
-    if (acontext == 0)
-        acontext = generation_alloc_context (pGenGCHeap->generation_of(0));
-
     // Only bother with this if the stress level is big enough and if nobody else is
     // doing it right now.  Note that some callers are inside the AllocLock and are
     // guaranteed synchronized.  But others are using AllocationContexts and have no
@@ -34496,10 +34494,6 @@ GCHeap::AllocLHeap( size_t size, uint32_t flags REQD_ALIGN_DCL)
 #endif //_PREFAST_
 #endif //MULTIPLE_HEAPS
 
-#ifndef FEATURE_REDHAWK
-    GCStress<gc_on_alloc>::MaybeTrigger(generation_alloc_context(hp->generation_of(0)));
-#endif // FEATURE_REDHAWK
-
     alloc_context* acontext = generation_alloc_context (hp->generation_of (max_generation+1));
 
     newAlloc = (Object*) hp->allocate_large_object (size + ComputeMaxStructAlignPadLarge(requiredAlignment), acontext->alloc_bytes_loh);
index c463ba7..f67aef7 100644 (file)
@@ -696,8 +696,9 @@ public:
     ===========================================================================
     */
 
-    // Returns TRUE if GC actually happens, otherwise FALSE
-    virtual BOOL StressHeap(gc_alloc_context* acontext = 0) = 0;
+    // Returns TRUE if GC actually happens, otherwise FALSE. The passed alloc context
+    // must not be null.
+    virtual BOOL StressHeap(gc_alloc_context* acontext) = 0;
 
     /*
     ===========================================================================
index 02bb0de..3e19579 100644 (file)
@@ -1759,7 +1759,10 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
     // Do the actual stress work
     //
 
-    if (!GCHeapUtilities::GetGCHeap()->StressHeap())
+    // BUG(github #10318) - when not using allocation contexts, the alloc lock
+    // must be acquired here. Until fixed, this assert prevents random heap corruption.
+    assert(GCHeapUtilities::UseThreadAllocationContexts());
+    if (!GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext()))
         UpdateGCStressInstructionWithoutGC ();
 
     // Must flush instruction cache before returning as instruction has been modified.
index 04487c6..edf92a9 100644 (file)
@@ -286,7 +286,12 @@ namespace _GCStress
     public:
         FORCEINLINE
         static void Trigger()
-        { GCHeapUtilities::GetGCHeap()->StressHeap(); }
+        {
+            // BUG(github #10318) - when not using allocation contexts, the alloc lock
+            // must be acquired here. Until fixed, this assert prevents random heap corruption.
+            _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
+            GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext());
+        }
 
         FORCEINLINE
         static void Trigger(::gc_alloc_context* acontext)
index 52c4aa6..10032fd 100644 (file)
@@ -3495,7 +3495,11 @@ void Thread::PerformPreemptiveGC()
     {
         GCX_COOP();
         m_bGCStressing = TRUE;
-        GCHeapUtilities::GetGCHeap()->StressHeap();
+
+        // BUG(github #10318) - when not using allocation contexts, the alloc lock
+        // must be acquired here. Until fixed, this assert prevents random heap corruption.
+        _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
+        GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext());
         m_bGCStressing = FALSE;
     }
     m_GCOnTransitionsOK = TRUE;