Skip to content

Commit ec8fb47

Browse files
Maoni Stephensmangod9
authored andcommitted
ApproxTotalBytesInUse
1 parent c8c0f29 commit ec8fb47

File tree

2 files changed

+93
-41
lines changed

2 files changed

+93
-41
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 87 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++)
@@ -32927,6 +32967,11 @@ void gc_heap::decommit_mark_array_by_seg (heap_segment* seg)
3292732967
}
3292832968
}
3292932969

32970+
bool gc_heap::should_update_end_mark_size()
32971+
{
32972+
return ((settings.condemned_generation == (max_generation - 1)) && (current_c_gc_state == c_gc_state_planning));
32973+
}
32974+
3293032975
void gc_heap::background_mark_phase ()
3293132976
{
3293232977
verify_mark_array_cleared();
@@ -33001,6 +33046,7 @@ void gc_heap::background_mark_phase ()
3300133046
bgc_begin_poh_size = total_poh_size;
3300233047
bgc_loh_size_increased = 0;
3300333048
bgc_poh_size_increased = 0;
33049+
background_soh_size_end_mark = 0;
3300433050

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

@@ -33481,6 +33527,8 @@ void gc_heap::background_mark_phase ()
3348133527
heap_segment_background_allocated (seg) = heap_segment_allocated (seg);
3348233528
}
3348333529

33530+
background_soh_size_end_mark += heap_segment_background_allocated (seg) - heap_segment_mem (seg);
33531+
3348433532
dprintf (3333, ("h%d gen%d seg %Ix (%Ix) background allocated is %Ix",
3348533533
heap_number, i, (size_t)(seg), heap_segment_mem (seg),
3348633534
heap_segment_background_allocated (seg)));
@@ -45097,11 +45145,11 @@ size_t GCHeap::GetTotalBytesInUse ()
4509745145
for (int i = 0; i < gc_heap::n_heaps; i++)
4509845146
{
4509945147
GCHeap* Hp = gc_heap::g_heaps [i]->vm_heap;
45100-
tot_size += Hp->ApproxTotalBytesInUse (FALSE);
45148+
tot_size += Hp->ApproxTotalBytesInUse();
4510145149
}
4510245150
return tot_size;
4510345151
#else
45104-
return ApproxTotalBytesInUse ();
45152+
return ApproxTotalBytesInUse();
4510545153
#endif //MULTIPLE_HEAPS
4510645154
}
4510745155

@@ -45156,58 +45204,56 @@ size_t GCHeap::ApproxTotalBytesInUse(BOOL small_heap_only)
4515645204
size_t totsize = 0;
4515745205
enter_spin_lock (&pGenGCHeap->gc_lock);
4515845206

45159-
// the complication with the following code is that background GC may
45160-
// remove the ephemeral segment while we are iterating
45161-
// if so, we retry a couple times and ultimately may report a slightly wrong result
45162-
for (int tries = 1; tries <= 3; tries++)
45207+
// For gen0 it's a bit complicated because we are currently allocating in it. We get the fragmentation first
45208+
// just so that we don't give a negative number for the resulting size.
45209+
generation* gen = pGenGCHeap->generation_of (0);
45210+
size_t gen0_frag = generation_free_list_space (gen) + generation_free_obj_space (gen);
45211+
uint8_t* current_alloc_allocated = pGenGCHeap->alloc_allocated;
45212+
heap_segment* current_eph_seg = pGenGCHeap->ephemeral_heap_segment;
45213+
size_t gen0_size = 0;
45214+
#ifdef USE_REGIONS
45215+
heap_segment* gen0_seg = generation_start_segment (gen);
45216+
while (gen0_seg)
4516345217
{
45164-
heap_segment* eph_seg = generation_allocation_segment (pGenGCHeap->generation_of (0));
45165-
// Get small block heap size info
45166-
totsize = (pGenGCHeap->alloc_allocated - heap_segment_mem (eph_seg));
45167-
heap_segment* seg1 = generation_start_segment (pGenGCHeap->generation_of (max_generation));
45168-
while ((seg1 != eph_seg) && (seg1 != nullptr)
45169-
#ifdef BACKGROUND_GC
45170-
&& (seg1 != pGenGCHeap->freeable_soh_segment)
45171-
#endif //BACKGROUND_GC
45172-
)
45218+
uint8_t* end = in_range_for_segment (current_alloc_allocated, gen0_seg) ?
45219+
current_alloc_allocated : heap_segment_allocated (gen0_seg);
45220+
gen0_size += end - heap_segment_mem (gen0_seg);
45221+
45222+
if (gen0_seg == current_eph_seg)
4517345223
{
45174-
#ifdef BACKGROUND_GC
45175-
if (!heap_segment_decommitted_p (seg1))
45176-
#endif //BACKGROUND_GC
45177-
{
45178-
totsize += heap_segment_allocated (seg1) -
45179-
heap_segment_mem (seg1);
45180-
}
45181-
seg1 = heap_segment_next (seg1);
45182-
}
45183-
if (seg1 == eph_seg)
4518445224
break;
45225+
}
4518545226
}
45227+
#else //USE_REGIONS
45228+
// For segments ephemeral seg does not change.
45229+
gen0_size = current_alloc_allocated - heap_segment_mem (current_eph_seg);
45230+
#endif //USE_REGIONS
4518645231

45187-
//discount the fragmentation
45188-
for (int i = 0; i <= max_generation; i++)
45232+
totsize = gen0_size - gen0_frag;
45233+
45234+
int stop_gen_index = max_generation;
45235+
45236+
if (gc_heap::current_c_gc_state == c_gc_state_planning)
45237+
{
45238+
// During BGC sweep since we can be deleting SOH segments, we avoid walking the segment
45239+
// list.
45240+
generation* oldest_gen = pGenGCHeap->generation_of (max_generation);
45241+
totsize = pGenGCHeap->background_soh_size_end_mark - generation_free_list_space (oldest_gen) - generation_free_obj_space (oldest_gen);
45242+
stop_gen_index--;
45243+
}
45244+
45245+
for (int i = (max_generation - 1); i <= stop_gen_index; i++)
4518945246
{
4519045247
generation* gen = pGenGCHeap->generation_of (i);
45191-
totsize -= (generation_free_list_space (gen) + generation_free_obj_space (gen));
45248+
totsize += pGenGCHeap->generation_size (i) - generation_free_list_space (gen) - generation_free_obj_space (gen);
4519245249
}
4519345250

4519445251
if (!small_heap_only)
4519545252
{
4519645253
for (int i = uoh_start_generation; i < total_generation_count; i++)
4519745254
{
45198-
heap_segment* seg2 = generation_start_segment (pGenGCHeap->generation_of (i));
45199-
45200-
while (seg2 != 0)
45201-
{
45202-
totsize += heap_segment_allocated (seg2) -
45203-
heap_segment_mem (seg2);
45204-
seg2 = heap_segment_next (seg2);
45205-
}
45206-
45207-
//discount the fragmentation
45208-
generation* uoh_gen = pGenGCHeap->generation_of (i);
45209-
size_t frag = generation_free_list_space (uoh_gen) + generation_free_obj_space (uoh_gen);
45210-
totsize -= frag;
45255+
generation* gen = pGenGCHeap->generation_of (i);
45256+
totsize += pGenGCHeap->generation_size (i) - generation_free_list_space (gen) - generation_free_obj_space (gen);
4521145257
}
4521245258
}
4521345259
leave_spin_lock (&pGenGCHeap->gc_lock);

src/coreclr/gc/gcpriv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

0 commit comments

Comments
 (0)