Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 81 additions & 42 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2532,13 +2532,15 @@ uint8_t** gc_heap::background_mark_stack_array = 0;

size_t gc_heap::background_mark_stack_array_length = 0;

BOOL gc_heap::processed_eph_overflow_p = FALSE;

#ifdef USE_REGIONS
BOOL gc_heap::background_overflow_p = FALSE;
#else //USE_REGIONS
uint8_t* gc_heap::background_min_overflow_address =0;

uint8_t* gc_heap::background_max_overflow_address =0;

BOOL gc_heap::processed_eph_overflow_p = FALSE;

#ifndef USE_REGIONS
uint8_t* gc_heap::background_min_soh_overflow_address =0;

uint8_t* gc_heap::background_max_soh_overflow_address =0;
Expand All @@ -2548,7 +2550,7 @@ heap_segment* gc_heap::saved_overflow_ephemeral_seg = 0;
heap_segment* gc_heap::saved_sweep_ephemeral_seg = 0;

uint8_t* gc_heap::saved_sweep_ephemeral_start = 0;
#endif //!USE_REGIONS
#endif //USE_REGIONS

Thread* gc_heap::bgc_thread = 0;

Expand Down Expand Up @@ -23429,6 +23431,21 @@ void gc_heap::mark_object (uint8_t* o THREAD_NUMBER_DCL)

#ifdef BACKGROUND_GC

#ifdef USE_REGIONS
void gc_heap::set_background_overflow_p (uint8_t* oo)
{
heap_segment* overflow_region = get_region_info_for_address (oo);
overflow_region->flags |= heap_segment_flags_overflow;
dprintf (3,("setting overflow flag for region %p", heap_segment_mem (overflow_region)));
#ifdef MULTIPLE_HEAPS
gc_heap* overflow_heap = heap_segment_heap (overflow_region);
#else
gc_heap* overflow_heap = nullptr;
#endif
overflow_heap->background_overflow_p = TRUE;
}
#endif //USE_REGIONS

void gc_heap::background_mark_simple1 (uint8_t* oo THREAD_NUMBER_DCL)
{
uint8_t** mark_stack_limit = &background_mark_stack_array[background_mark_stack_array_length];
Expand Down Expand Up @@ -23495,9 +23512,13 @@ void gc_heap::background_mark_simple1 (uint8_t* oo THREAD_NUMBER_DCL)
}
else
{
dprintf (3,("mark stack overflow for object %Ix ", (size_t)oo));
dprintf (3,("background mark stack overflow for object %Ix ", (size_t)oo));
#ifdef USE_REGIONS
set_background_overflow_p (oo);
#else //USE_REGIONS
background_min_overflow_address = min (background_min_overflow_address, oo);
background_max_overflow_address = max (background_max_overflow_address, oo);
#endif //USE_REGIONS
}
}
else
Expand Down Expand Up @@ -23609,9 +23630,13 @@ void gc_heap::background_mark_simple1 (uint8_t* oo THREAD_NUMBER_DCL)
}
else
{
dprintf (3,("mark stack overflow for object %Ix ", (size_t)oo));
dprintf (3,("background mark stack overflow for object %Ix ", (size_t)oo));
#ifdef USE_REGIONS
set_background_overflow_p (oo);
#else //USE_REGIONS
background_min_overflow_address = min (background_min_overflow_address, oo);
background_max_overflow_address = max (background_max_overflow_address, oo);
#endif //USE_REGIONS
}
}
}
Expand Down Expand Up @@ -23887,13 +23912,13 @@ uint8_t* gc_heap::background_first_overflow (uint8_t* min_add,
BOOL concurrent_p,
BOOL small_object_p)
{
#ifdef USE_REGIONS
return heap_segment_mem (seg);
#else
uint8_t* o = 0;

if (small_object_p)
{
#ifdef USE_REGIONS
return find_first_object (min_add, heap_segment_mem (seg));
#else
if (in_range_for_segment (min_add, seg))
{
// min_add was the beginning of gen1 when we did the concurrent
Expand All @@ -23919,11 +23944,11 @@ uint8_t* gc_heap::background_first_overflow (uint8_t* min_add,
}
}
}
#endif //USE_REGIONS
}

o = max (heap_segment_mem (seg), min_add);
return o;
#endif //USE_REGIONS
}

void gc_heap::background_process_mark_overflow_internal (uint8_t* min_add, uint8_t* max_add,
Expand All @@ -23948,7 +23973,9 @@ void gc_heap::background_process_mark_overflow_internal (uint8_t* min_add, uint8

exclusive_sync* loh_alloc_lock = 0;

#ifndef USE_REGIONS
dprintf (2,("Processing Mark overflow [%Ix %Ix]", (size_t)min_add, (size_t)max_add));
#endif
#ifdef MULTIPLE_HEAPS
// We don't have each heap scan all heaps concurrently because we are worried about
// multiple threads calling things like find_first_object.
Expand Down Expand Up @@ -23981,9 +24008,14 @@ void gc_heap::background_process_mark_overflow_internal (uint8_t* min_add, uint8
#ifdef USE_REGIONS
if (heap_segment_overflow_p (seg))
{
assert (!concurrent_p);
current_min_add = max (heap_segment_mem (seg), min_add);
current_max_add = min (heap_segment_allocated (seg), max_add);
seg->flags &= ~heap_segment_flags_overflow;
current_min_add = heap_segment_mem (seg);
current_max_add = heap_segment_allocated (seg);
dprintf (2,("Processing Mark overflow [%Ix %Ix]", (size_t)current_min_add, (size_t)current_max_add));
}
else
{
current_min_add = current_max_add = 0;
}
#endif //USE_REGIONS
uint8_t* o = hp->background_first_overflow (current_min_add, seg, concurrent_p, small_object_segments);
Expand Down Expand Up @@ -24034,15 +24066,19 @@ void gc_heap::background_process_mark_overflow_internal (uint8_t* min_add, uint8
}
}

dprintf (2, ("went through overflow objects in segment %Ix (%d) (so far %Id marked)",
heap_segment_mem (seg), (small_object_segments ? 0 : 1), total_marked_objects));

#ifdef USE_REGIONS
if (current_max_add != 0)
#endif //USE_REGIONS
{
dprintf (2, ("went through overflow objects in segment %Ix (%d) (so far %Id marked)",
heap_segment_mem (seg), (small_object_segments ? 0 : 1), total_marked_objects));
}
#ifndef USE_REGIONS
if (concurrent_p && (seg == hp->saved_overflow_ephemeral_seg))
{
break;
}
#endif //USE_REGIONS
#endif //!USE_REGIONS
seg = heap_segment_next_in_range (seg);
}

Expand Down Expand Up @@ -24071,36 +24107,18 @@ BOOL gc_heap::background_process_mark_overflow (BOOL concurrent_p)
if (concurrent_p)
{
assert (!processed_eph_overflow_p);

#ifndef USE_REGIONS
if ((background_max_overflow_address != 0) &&
(background_min_overflow_address != MAX_PTR))
{
#ifdef USE_REGIONS
// We don't want to step into the ephemeral regions so remember these regions and
// be sure to process them later. An FGC cannot happen while we are going through
// the region lists.
for (int i = 0; i < max_generation; i++)
{
heap_segment* region = generation_start_segment (generation_of (i));
while (region)
{
if ((heap_segment_mem (region) <= background_max_overflow_address) &&
(heap_segment_allocated (region) >= background_min_overflow_address))
{
region->flags |= heap_segment_flags_overflow;
}
region = heap_segment_next (region);
}
}
#else //USE_REGIONS
// We have overflow to process but we know we can't process the ephemeral generations
// now (we actually could process till the current gen1 start but since we are going to
// make overflow per segment, for now I'll just stop at the saved gen1 start.
saved_overflow_ephemeral_seg = ephemeral_heap_segment;
background_max_soh_overflow_address = heap_segment_reserved (saved_overflow_ephemeral_seg);
background_min_soh_overflow_address = generation_allocation_start (generation_of (max_generation - 1));
#endif //USE_REGIONS
}
#endif //!USE_REGIONS
}
else
{
Expand All @@ -24114,12 +24132,18 @@ BOOL gc_heap::background_process_mark_overflow (BOOL concurrent_p)
{
// if there was no more overflow we just need to process what we didn't process
// on the saved ephemeral segment.
#ifdef USE_REGIONS
if (!background_overflow_p)
#else
if ((background_max_overflow_address == 0) && (background_min_overflow_address == MAX_PTR))
#endif //USE_REGIONS
{
dprintf (2, ("final processing mark overflow - no more overflow since last time"));
grow_mark_array_p = FALSE;
}
#ifndef USE_REGIONS
#ifdef USE_REGIONS
background_overflow_p = TRUE;
#else
background_min_overflow_address = min (background_min_overflow_address,
background_min_soh_overflow_address);
background_max_overflow_address = max (background_max_overflow_address,
Expand All @@ -24131,8 +24155,12 @@ BOOL gc_heap::background_process_mark_overflow (BOOL concurrent_p)

BOOL overflow_p = FALSE;
recheck:
#ifdef USE_REGIONS
if (background_overflow_p)
#else
if ((! ((background_max_overflow_address == 0)) ||
! ((background_min_overflow_address == MAX_PTR))))
#endif
{
overflow_p = TRUE;

Expand All @@ -24155,11 +24183,17 @@ BOOL gc_heap::background_process_mark_overflow (BOOL concurrent_p)
grow_mark_array_p = TRUE;
}

#ifdef USE_REGIONS
uint8_t* min_add = 0;
uint8_t* max_add = 0;
background_overflow_p = FALSE;
#else
uint8_t* min_add = background_min_overflow_address;
uint8_t* max_add = background_max_overflow_address;

background_max_overflow_address = 0;
background_min_overflow_address = MAX_PTR;
#endif

background_process_mark_overflow_internal (min_add, max_add, concurrent_p);
if (!concurrent_p)
Expand Down Expand Up @@ -32375,6 +32409,7 @@ void gc_heap::background_scan_dependent_handles (ScanContext *sc)

if (!s_fScanRequired)
{
#ifndef USE_REGIONS
uint8_t* all_heaps_max = 0;
uint8_t* all_heaps_min = MAX_PTR;
int i;
Expand All @@ -32390,6 +32425,7 @@ void gc_heap::background_scan_dependent_handles (ScanContext *sc)
g_heaps[i]->background_max_overflow_address = all_heaps_max;
g_heaps[i]->background_min_overflow_address = all_heaps_min;
}
#endif //!USE_REGIONS
}

dprintf(2, ("Starting all gc thread mark stack overflow processing"));
Expand Down Expand Up @@ -32920,12 +32956,14 @@ void gc_heap::background_mark_phase ()
bpromoted_bytes (heap_number) = 0;
static uint32_t num_sizedrefs = 0;

#ifdef USE_REGIONS
background_overflow_p = FALSE;
#else
background_min_overflow_address = MAX_PTR;
background_max_overflow_address = 0;
#ifndef USE_REGIONS
background_min_soh_overflow_address = MAX_PTR;
background_max_soh_overflow_address = 0;
#endif //!USE_REGIONS
#endif //USE_REGIONS
processed_eph_overflow_p = FALSE;

//set up the mark lists from g_mark_list
Expand Down Expand Up @@ -33125,7 +33163,7 @@ void gc_heap::background_mark_phase ()

enable_preemptive ();

#ifdef MULTIPLE_HEAPS
#if defined(MULTIPLE_HEAPS) && !defined(USE_REGIONS)
bgc_t_join.join(this, gc_join_concurrent_overflow);
if (bgc_t_join.joined())
{
Expand All @@ -33142,6 +33180,7 @@ void gc_heap::background_mark_phase ()
all_heaps_max = g_heaps[i]->background_max_overflow_address;
if (all_heaps_min > g_heaps[i]->background_min_overflow_address)
all_heaps_min = g_heaps[i]->background_min_overflow_address;

}
for (i = 0; i < n_heaps; i++)
{
Expand All @@ -33151,7 +33190,7 @@ void gc_heap::background_mark_phase ()
dprintf(3, ("Starting all bgc threads after updating the overflow info"));
bgc_t_join.restart();
}
#endif //MULTIPLE_HEAPS
#endif //MULTIPLE_HEAPS && !USE_REGIONS

disable_preemptive (true);

Expand Down
19 changes: 13 additions & 6 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2466,6 +2466,10 @@ class gc_heap
void verify_mark_bits_cleared (uint8_t* obj, size_t s);
PER_HEAP
void clear_all_mark_array();
#ifdef USE_REGIONS
PER_HEAP
void set_background_overflow_p (uint8_t* oo);
#endif

#ifdef BGC_SERVO_TUNING

Expand Down Expand Up @@ -4282,18 +4286,21 @@ class gc_heap
PER_HEAP
size_t background_mark_stack_array_length;

// We can't process the ephemeral range concurrently so we
// wait till final mark to process it.
PER_HEAP
uint8_t* background_min_overflow_address;
BOOL processed_eph_overflow_p;

#ifdef USE_REGIONS
PER_HEAP
uint8_t* background_max_overflow_address;
BOOL background_overflow_p;
#else
PER_HEAP
uint8_t* background_min_overflow_address;

// We can't process the ephemeral range concurrently so we
// wait till final mark to process it.
PER_HEAP
BOOL processed_eph_overflow_p;
uint8_t* background_max_overflow_address;

#ifndef USE_REGIONS
PER_HEAP
uint8_t* background_min_soh_overflow_address;

Expand Down