Skip to content

Commit cf91716

Browse files
mangod9Maoni Stephens
andauthored
Enable GC regions by default (#59283)
* Enable regions by default * ApproxTotalBytesInUse * one line fix * initialize CurrentThread before initializing GC Without this fix enabling Regions is failing AOT tests on checked build. * use GetCurrentThreadIfAvailable within GCToEEInterface::GetThread This is similar to GCToEEInterface::GetThread implementation in the runtime. Co-authored-by: Maoni Stephens <[email protected]>
1 parent b389de5 commit cf91716

File tree

3 files changed

+98
-44
lines changed

3 files changed

+98
-44
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 89 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,6 +2522,8 @@ size_t gc_heap::bgc_loh_size_increased = 0;
25222522

25232523
size_t gc_heap::bgc_poh_size_increased = 0;
25242524

2525+
size_t gc_heap::background_soh_size_end_mark = 0;
2526+
25252527
size_t gc_heap::background_soh_alloc_count = 0;
25262528

25272529
size_t gc_heap::background_uoh_alloc_count = 0;
@@ -28892,6 +28894,14 @@ void gc_heap::plan_phase (int condemned_gen_number)
2889228894
{
2889328895
dprintf (2,( "**** Doing Compacting GC ****"));
2889428896

28897+
#if defined(USE_REGIONS) && defined(BACKGROUND_GC)
28898+
if (should_update_end_mark_size())
28899+
{
28900+
background_soh_size_end_mark += generation_end_seg_allocated (older_gen) -
28901+
r_older_gen_end_seg_allocated;
28902+
}
28903+
#endif //USE_REGIONS && BACKGROUND_GC
28904+
2889528905
#ifndef USE_REGIONS
2889628906
if (should_expand)
2889728907
{
@@ -29396,6 +29406,13 @@ void gc_heap::fix_generation_bounds (int condemned_gen_number,
2939629406
}
2939729407
}
2939829408
#endif //MULTIPLE_HEAPS
29409+
29410+
#ifdef BACKGROUND_GC
29411+
if (should_update_end_mark_size())
29412+
{
29413+
background_soh_size_end_mark = generation_size (max_generation);
29414+
}
29415+
#endif //BACKGROUND_GC
2939929416
#endif //!USE_REGIONS
2940029417

2940129418
{
@@ -29614,6 +29631,14 @@ void gc_heap::thread_final_regions (bool compact_p)
2961429631
generation_final_regions[gen_idx].tail = generation_tail_region (gen);
2961529632
}
2961629633

29634+
#ifdef BACKGROUND_GC
29635+
heap_segment* max_gen_tail_region = 0;
29636+
if (should_update_end_mark_size())
29637+
{
29638+
max_gen_tail_region = generation_final_regions[max_generation].tail;
29639+
}
29640+
#endif //BACKGROUND_GC
29641+
2961729642
// Step 2: for each region in the condemned generations, we thread it onto its planned generation
2961829643
// in our generation_final_regions array.
2961929644
for (int gen_idx = condemned_gen_number; gen_idx >= 0; gen_idx--)
@@ -29664,6 +29689,21 @@ void gc_heap::thread_final_regions (bool compact_p)
2966429689
}
2966529690
}
2966629691

29692+
#ifdef BACKGROUND_GC
29693+
if (max_gen_tail_region)
29694+
{
29695+
max_gen_tail_region = heap_segment_next (max_gen_tail_region);
29696+
29697+
while (max_gen_tail_region)
29698+
{
29699+
background_soh_size_end_mark += heap_segment_allocated (max_gen_tail_region) -
29700+
heap_segment_mem (max_gen_tail_region);
29701+
29702+
max_gen_tail_region = heap_segment_next (max_gen_tail_region);
29703+
}
29704+
}
29705+
#endif //BACKGROUND_GC
29706+
2966729707
// Step 4: if a generation doesn't have any regions, we need to get a new one for it;
2966829708
// otherwise we just set the head region as the start region for that generation.
2966929709
for (int gen_idx = 0; gen_idx <= max_generation; gen_idx++)
@@ -32933,6 +32973,11 @@ void gc_heap::decommit_mark_array_by_seg (heap_segment* seg)
3293332973
}
3293432974
}
3293532975

32976+
bool gc_heap::should_update_end_mark_size()
32977+
{
32978+
return ((settings.condemned_generation == (max_generation - 1)) && (current_c_gc_state == c_gc_state_planning));
32979+
}
32980+
3293632981
void gc_heap::background_mark_phase ()
3293732982
{
3293832983
verify_mark_array_cleared();
@@ -33007,6 +33052,7 @@ void gc_heap::background_mark_phase ()
3300733052
bgc_begin_poh_size = total_poh_size;
3300833053
bgc_loh_size_increased = 0;
3300933054
bgc_poh_size_increased = 0;
33055+
background_soh_size_end_mark = 0;
3301033056

3301133057
dprintf (GTC_LOG, ("BM: h%d: loh: %Id, soh: %Id, poh: %Id", heap_number, total_loh_size, total_soh_size, total_poh_size));
3301233058

@@ -33487,6 +33533,8 @@ void gc_heap::background_mark_phase ()
3348733533
heap_segment_background_allocated (seg) = heap_segment_allocated (seg);
3348833534
}
3348933535

33536+
background_soh_size_end_mark += heap_segment_background_allocated (seg) - heap_segment_mem (seg);
33537+
3349033538
dprintf (3333, ("h%d gen%d seg %Ix (%Ix) background allocated is %Ix",
3349133539
heap_number, i, (size_t)(seg), heap_segment_mem (seg),
3349233540
heap_segment_background_allocated (seg)));
@@ -45103,11 +45151,11 @@ size_t GCHeap::GetTotalBytesInUse ()
4510345151
for (int i = 0; i < gc_heap::n_heaps; i++)
4510445152
{
4510545153
GCHeap* Hp = gc_heap::g_heaps [i]->vm_heap;
45106-
tot_size += Hp->ApproxTotalBytesInUse (FALSE);
45154+
tot_size += Hp->ApproxTotalBytesInUse();
4510745155
}
4510845156
return tot_size;
4510945157
#else
45110-
return ApproxTotalBytesInUse ();
45158+
return ApproxTotalBytesInUse();
4511145159
#endif //MULTIPLE_HEAPS
4511245160
}
4511345161

@@ -45162,58 +45210,58 @@ size_t GCHeap::ApproxTotalBytesInUse(BOOL small_heap_only)
4516245210
size_t totsize = 0;
4516345211
enter_spin_lock (&pGenGCHeap->gc_lock);
4516445212

45165-
// the complication with the following code is that background GC may
45166-
// remove the ephemeral segment while we are iterating
45167-
// if so, we retry a couple times and ultimately may report a slightly wrong result
45168-
for (int tries = 1; tries <= 3; tries++)
45213+
// For gen0 it's a bit complicated because we are currently allocating in it. We get the fragmentation first
45214+
// just so that we don't give a negative number for the resulting size.
45215+
generation* gen = pGenGCHeap->generation_of (0);
45216+
size_t gen0_frag = generation_free_list_space (gen) + generation_free_obj_space (gen);
45217+
uint8_t* current_alloc_allocated = pGenGCHeap->alloc_allocated;
45218+
heap_segment* current_eph_seg = pGenGCHeap->ephemeral_heap_segment;
45219+
size_t gen0_size = 0;
45220+
#ifdef USE_REGIONS
45221+
heap_segment* gen0_seg = generation_start_segment (gen);
45222+
while (gen0_seg)
4516945223
{
45170-
heap_segment* eph_seg = generation_allocation_segment (pGenGCHeap->generation_of (0));
45171-
// Get small block heap size info
45172-
totsize = (pGenGCHeap->alloc_allocated - heap_segment_mem (eph_seg));
45173-
heap_segment* seg1 = generation_start_segment (pGenGCHeap->generation_of (max_generation));
45174-
while ((seg1 != eph_seg) && (seg1 != nullptr)
45175-
#ifdef BACKGROUND_GC
45176-
&& (seg1 != pGenGCHeap->freeable_soh_segment)
45177-
#endif //BACKGROUND_GC
45178-
)
45224+
uint8_t* end = in_range_for_segment (current_alloc_allocated, gen0_seg) ?
45225+
current_alloc_allocated : heap_segment_allocated (gen0_seg);
45226+
gen0_size += end - heap_segment_mem (gen0_seg);
45227+
45228+
if (gen0_seg == current_eph_seg)
4517945229
{
45180-
#ifdef BACKGROUND_GC
45181-
if (!heap_segment_decommitted_p (seg1))
45182-
#endif //BACKGROUND_GC
45183-
{
45184-
totsize += heap_segment_allocated (seg1) -
45185-
heap_segment_mem (seg1);
45186-
}
45187-
seg1 = heap_segment_next (seg1);
45188-
}
45189-
if (seg1 == eph_seg)
4519045230
break;
45231+
}
45232+
45233+
gen0_seg = heap_segment_next (gen0_seg);
4519145234
}
45235+
#else //USE_REGIONS
45236+
// For segments ephemeral seg does not change.
45237+
gen0_size = current_alloc_allocated - heap_segment_mem (current_eph_seg);
45238+
#endif //USE_REGIONS
4519245239

45193-
//discount the fragmentation
45194-
for (int i = 0; i <= max_generation; i++)
45240+
totsize = gen0_size - gen0_frag;
45241+
45242+
int stop_gen_index = max_generation;
45243+
45244+
if (gc_heap::current_c_gc_state == c_gc_state_planning)
45245+
{
45246+
// During BGC sweep since we can be deleting SOH segments, we avoid walking the segment
45247+
// list.
45248+
generation* oldest_gen = pGenGCHeap->generation_of (max_generation);
45249+
totsize = pGenGCHeap->background_soh_size_end_mark - generation_free_list_space (oldest_gen) - generation_free_obj_space (oldest_gen);
45250+
stop_gen_index--;
45251+
}
45252+
45253+
for (int i = (max_generation - 1); i <= stop_gen_index; i++)
4519545254
{
4519645255
generation* gen = pGenGCHeap->generation_of (i);
45197-
totsize -= (generation_free_list_space (gen) + generation_free_obj_space (gen));
45256+
totsize += pGenGCHeap->generation_size (i) - generation_free_list_space (gen) - generation_free_obj_space (gen);
4519845257
}
4519945258

4520045259
if (!small_heap_only)
4520145260
{
4520245261
for (int i = uoh_start_generation; i < total_generation_count; i++)
4520345262
{
45204-
heap_segment* seg2 = generation_start_segment (pGenGCHeap->generation_of (i));
45205-
45206-
while (seg2 != 0)
45207-
{
45208-
totsize += heap_segment_allocated (seg2) -
45209-
heap_segment_mem (seg2);
45210-
seg2 = heap_segment_next (seg2);
45211-
}
45212-
45213-
//discount the fragmentation
45214-
generation* uoh_gen = pGenGCHeap->generation_of (i);
45215-
size_t frag = generation_free_list_space (uoh_gen) + generation_free_obj_space (uoh_gen);
45216-
totsize -= frag;
45263+
generation* gen = pGenGCHeap->generation_of (i);
45264+
totsize += pGenGCHeap->generation_size (i) - generation_free_list_space (gen) - generation_free_obj_space (gen);
4521745265
}
4521845266
}
4521945267
leave_spin_lock (&pGenGCHeap->gc_lock);

src/coreclr/gc/gcpriv.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ inline void FATAL_GC_ERROR()
5151
//
5252
// This means any empty regions can be freely used for any generation. For
5353
// Server GC we will balance regions between heaps.
54-
// For now enable regions by default for only StandAlone GC builds
55-
#if defined (HOST_64BIT) && defined (BUILD_AS_STANDALONE)
54+
// For now disable regions StandAlone GC builds
55+
#if defined (HOST_64BIT) && !defined (BUILD_AS_STANDALONE)
5656
#define USE_REGIONS
5757
#endif //HOST_64BIT && BUILD_AS_STANDALONE
5858

@@ -3440,6 +3440,9 @@ class gc_heap
34403440
PER_HEAP
34413441
void decommit_mark_array_by_seg (heap_segment* seg);
34423442

3443+
PER_HEAP_ISOLATED
3444+
bool should_update_end_mark_size();
3445+
34433446
PER_HEAP
34443447
void background_mark_phase();
34453448

@@ -4268,6 +4271,9 @@ class gc_heap
42684271
PER_HEAP
42694272
size_t bgc_poh_size_increased;
42704273

4274+
PER_HEAP
4275+
size_t background_soh_size_end_mark;
4276+
42714277
PER_HEAP
42724278
size_t background_soh_alloc_count;
42734279

src/coreclr/nativeaot/Runtime/gcrhenv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ void GCToEEInterface::DisablePreemptiveGC()
923923
Thread* GCToEEInterface::GetThread()
924924
{
925925
#ifndef DACCESS_COMPILE
926-
return ThreadStore::GetCurrentThread();
926+
return ThreadStore::GetCurrentThreadIfAvailable();
927927
#else
928928
return NULL;
929929
#endif

0 commit comments

Comments
 (0)