@@ -2522,6 +2522,8 @@ size_t gc_heap::bgc_loh_size_increased = 0;
25222522
25232523size_t gc_heap::bgc_poh_size_increased = 0;
25242524
2525+ size_t gc_heap::background_soh_size_end_mark = 0;
2526+
25252527size_t gc_heap::background_soh_alloc_count = 0;
25262528
25272529size_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+
3293632981void 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);
0 commit comments