From: Sean Gillespie Date: Wed, 22 Mar 2017 17:25:08 +0000 (-0700) Subject: Fix an issue where GCStress allocated objects using the Gen 0 alloc context (dotnet... X-Git-Tag: submit/tizen/20210909.063632~11030^2~7613 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=200b9df7eb7b17a822e584169f94a54da8def792;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix an issue where GCStress allocated objects using the Gen 0 alloc context (dotnet/coreclr#10322) * 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 --- diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index b58f4cc..a217563 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -34101,6 +34101,7 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context) { #if defined(STRESS_HEAP) && !defined(FEATURE_REDHAWK) alloc_context* acontext = static_cast(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::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); diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h index c463ba7..f67aef7 100644 --- a/src/coreclr/src/gc/gcinterface.h +++ b/src/coreclr/src/gc/gcinterface.h @@ -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; /* =========================================================================== diff --git a/src/coreclr/src/vm/gccover.cpp b/src/coreclr/src/vm/gccover.cpp index 02bb0de..3e19579 100644 --- a/src/coreclr/src/vm/gccover.cpp +++ b/src/coreclr/src/vm/gccover.cpp @@ -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. diff --git a/src/coreclr/src/vm/gcstress.h b/src/coreclr/src/vm/gcstress.h index 04487c6..edf92a9 100644 --- a/src/coreclr/src/vm/gcstress.h +++ b/src/coreclr/src/vm/gcstress.h @@ -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) diff --git a/src/coreclr/src/vm/threadsuspend.cpp b/src/coreclr/src/vm/threadsuspend.cpp index 52c4aa6..10032fd 100644 --- a/src/coreclr/src/vm/threadsuspend.cpp +++ b/src/coreclr/src/vm/threadsuspend.cpp @@ -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;