From 697ac03fe4e064362f9df0fdbe35b8ef56781dd2 Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Thu, 10 Jun 2021 18:07:32 +0200 Subject: [PATCH] Fix mark overflow for regions (#53929) Test GC\Scenarios\Boxing\variantlinklist\variantlinklist encountered a mark stack overflow that we didn't handle correctly in the regions case. The problem was that this was a gen 2 GC, and we didn't iterate over the gen 0 and gen 1 regions, so the objects causing the mark stack overflow were in fact not revisited. The fix is to iterate starting from gen 0 rather than the condemned generation. I added an assert to make sure process_mark_overflow_internal has found at least one marked object to process - unfortunately, we can check this only for WKS GC. --- src/coreclr/gc/gc.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index b73c024..64ec770 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -22290,7 +22290,7 @@ inline void gc_heap::mark_object (uint8_t* o THREAD_NUMBER_DCL) { #ifdef USE_REGIONS - if (is_in_condemned_gc (o)) + if ((o != nullptr) && is_in_condemned_gc (o)) { mark_object_simple (&o THREAD_NUMBER_ARG); } @@ -23314,7 +23314,10 @@ void gc_heap::process_mark_overflow_internal (int condemned_gen_number, #endif //MULTIPLE_HEAPS BOOL full_p = (condemned_gen_number == max_generation); - dprintf(3,("Processing Mark overflow [%Ix %Ix]", (size_t)min_add, (size_t)max_add)); + dprintf(3,("Processing Mark overflow [%Ix %Ix]", (size_t)min_add, (size_t)max_add)); + + size_t obj_count = 0; + #ifdef MULTIPLE_HEAPS for (int hi = 0; hi < n_heaps; hi++) { @@ -23323,11 +23326,10 @@ void gc_heap::process_mark_overflow_internal (int condemned_gen_number, #else { gc_heap* hp = 0; - #endif //MULTIPLE_HEAPS int gen_limit = full_p ? total_generation_count : condemned_gen_number + 1; - for (int i = condemned_gen_number; i < gen_limit; i++) + for (int i = get_stop_generation_index (condemned_gen_number); i < gen_limit; i++) { generation* gen = hp->generation_of (i); heap_segment* seg = heap_segment_in_range (generation_start_segment (gen)); @@ -23347,6 +23349,7 @@ void gc_heap::process_mark_overflow_internal (int condemned_gen_number, if (marked (o)) { mark_through_object (o, TRUE THREAD_NUMBER_ARG); + obj_count++; } o = o + Align (size (o), align_const); @@ -23355,6 +23358,10 @@ void gc_heap::process_mark_overflow_internal (int condemned_gen_number, seg = heap_segment_next_in_range (seg); } } +#ifndef MULTIPLE_HEAPS + // we should have found at least one object + assert (obj_count > 0); +#endif //MULTIPLE_HEAPS } } -- 2.7.4