diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 9a594fbc2d4721..64ef8a56d20e5f 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -32150,11 +32150,7 @@ void gc_heap::walk_relocation (void* profiling_context, record_surv_fn fn) generation* condemned_gen = generation_of (i); heap_segment* current_heap_segment = heap_segment_rw (generation_start_segment (condemned_gen)); #ifdef USE_REGIONS - while (current_heap_segment && heap_segment_swept_in_plan (current_heap_segment)) - { - // TODO: Walk the heap segment and report the plugs. - current_heap_segment = heap_segment_next_rw (current_heap_segment); - } + current_heap_segment = walk_relocation_sip (current_heap_segment, profiling_context, fn); if (!current_heap_segment) continue; #endif // USE_REGIONS @@ -32187,11 +32183,7 @@ void gc_heap::walk_relocation (void* profiling_context, record_surv_fn fn) } current_heap_segment = heap_segment_next_rw (current_heap_segment); #ifdef USE_REGIONS - while (current_heap_segment && heap_segment_swept_in_plan (current_heap_segment)) - { - // TODO: Walk the heap segment and report the plugs. - current_heap_segment = heap_segment_next_rw (current_heap_segment); - } + current_heap_segment = walk_relocation_sip (current_heap_segment, profiling_context, fn); #endif // USE_REGIONS if (current_heap_segment) { @@ -32218,6 +32210,45 @@ void gc_heap::walk_relocation (void* profiling_context, record_surv_fn fn) } } +#ifdef USE_REGIONS +heap_segment* gc_heap::walk_relocation_sip (heap_segment* current_heap_segment, void* profiling_context, record_surv_fn fn) +{ + while (current_heap_segment && heap_segment_swept_in_plan (current_heap_segment)) + { + uint8_t* start = heap_segment_mem (current_heap_segment); + uint8_t* end = heap_segment_allocated (current_heap_segment); + uint8_t* obj = start; + uint8_t* plug_start = nullptr; + while (obj < end) + { + if (((CObjectHeader*)obj)->IsFree()) + { + if (plug_start) + { + fn (plug_start, obj, 0, profiling_context, false, false); + plug_start = nullptr; + } + } + else + { + if (!plug_start) + { + plug_start = obj; + } + } + + obj += Align (size (obj)); + } + if (plug_start) + { + fn (plug_start, end, 0, profiling_context, false, false); + } + current_heap_segment = heap_segment_next_rw (current_heap_segment); + } + return current_heap_segment; +} +#endif // USE_REGIONS + void gc_heap::walk_survivors (record_surv_fn fn, void* context, walk_surv_type type) { if (type == walk_for_gc) diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 0f042baa6018f1..8b364071286e0c 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -1647,7 +1647,10 @@ class gc_heap PER_HEAP void walk_relocation (void* profiling_context, record_surv_fn fn); - +#ifdef USE_REGIONS + PER_HEAP + heap_segment* walk_relocation_sip (heap_segment* current_heap_segment, void* profiling_context, record_surv_fn fn); +#endif // USE_REGIONS PER_HEAP void walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args);