Skip to content

Commit bf83d79

Browse files
authored
Optimize region count (#56471)
We have a couple of arrays with an entry per region - instead of iterating over all the regions that we have reserved address space for, iterate just over the regions actually in use. Arrays affected by this are mark_list_piece_start, mark_list_piece_end, survived_per_region and old_card_survived per_region. To avoid having inconsistent counts, we get the count of regions actually in use at the start of mark_phase. Any regions added during GC should not matter, because they shouldn't contain any marked objects. While the region allocator has provisions to allocate regions from the highest addresses down, we don't use that facility now. If we do, the code to iterate through the used regions will need to get more sophisticated. I put an assert that would fire in this case.
1 parent 5089894 commit bf83d79

File tree

2 files changed

+14
-13
lines changed

2 files changed

+14
-13
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,7 @@ bool affinity_config_specified_p = false;
22952295
#ifdef USE_REGIONS
22962296
region_allocator global_region_allocator;
22972297
uint8_t*(*initial_regions)[total_generation_count][2] = nullptr;
2298+
size_t gc_heap::region_count = 0;
22982299
#endif //USE_REGIONS
22992300

23002301
#ifdef BACKGROUND_GC
@@ -3512,12 +3513,6 @@ size_t get_basic_region_index_for_address (uint8_t* address)
35123513
return (basic_region_index - ((size_t)g_gc_lowest_address >> gc_heap::min_segment_size_shr));
35133514
}
35143515

3515-
inline
3516-
size_t get_total_region_count()
3517-
{
3518-
return (get_basic_region_index_for_address (g_gc_highest_address) + 1);
3519-
}
3520-
35213516
// Go from a random address to its region info. The random address could be
35223517
// in one of the basic regions of a larger region so we need to check for that.
35233518
inline
@@ -9741,7 +9736,6 @@ size_t gc_heap::sort_mark_list()
97419736

97429737
#ifdef USE_REGIONS
97439738
// first set the pieces for all regions to empty
9744-
size_t region_count = get_total_region_count();
97459739
assert (g_mark_list_piece_size >= region_count);
97469740
for (size_t region_index = 0; region_index < region_count; region_index++)
97479741
{
@@ -21140,7 +21134,6 @@ size_t gc_heap::get_promoted_bytes()
2114021134
}
2114121135

2114221136
dprintf (3, ("h%d getting surv", heap_number));
21143-
size_t region_count = get_total_region_count();
2114421137
size_t promoted = 0;
2114521138
for (size_t i = 0; i < region_count; i++)
2114621139
{
@@ -23936,6 +23929,7 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p)
2393623929

2393723930
#ifdef USE_REGIONS
2393823931
special_sweep_p = false;
23932+
region_count = global_region_allocator.get_used_region_count();
2393923933
grow_mark_list_piece();
2394023934
#endif //USE_REGIONS
2394123935

@@ -24004,7 +23998,7 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p)
2400423998
#endif //MULTIPLE_HEAPS
2400523999
survived_per_region = (size_t*)&g_mark_list_piece[heap_number * 2 * g_mark_list_piece_size];
2400624000
old_card_survived_per_region = (size_t*)&survived_per_region[g_mark_list_piece_size];
24007-
size_t region_info_to_clear = get_total_region_count() * sizeof (size_t);
24001+
size_t region_info_to_clear = region_count * sizeof (size_t);
2400824002
memset (survived_per_region, 0, region_info_to_clear);
2400924003
memset (old_card_survived_per_region, 0, region_info_to_clear);
2401024004
}
@@ -26215,7 +26209,6 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c
2621526209

2621626210
void gc_heap::grow_mark_list_piece()
2621726211
{
26218-
size_t region_count = get_total_region_count();
2621926212
if (g_mark_list_piece_size < region_count)
2622026213
{
2622126214
delete[] g_mark_list_piece;
@@ -26240,11 +26233,10 @@ void gc_heap::save_current_survived()
2624026233
{
2624126234
if (!survived_per_region) return;
2624226235

26243-
size_t region_info_to_copy = get_total_region_count() * sizeof (size_t);
26236+
size_t region_info_to_copy = region_count * sizeof (size_t);
2624426237
memcpy (old_card_survived_per_region, survived_per_region, region_info_to_copy);
2624526238

2624626239
#ifdef _DEBUG
26247-
size_t region_count = get_total_region_count();
2624826240
for (size_t region_index = 0; region_index < region_count; region_index++)
2624926241
{
2625026242
if (survived_per_region[region_index] != 0)
@@ -26261,7 +26253,6 @@ void gc_heap::update_old_card_survived()
2626126253
{
2626226254
if (!survived_per_region) return;
2626326255

26264-
size_t region_count = get_total_region_count();
2626526256
for (size_t region_index = 0; region_index < region_count; region_index++)
2626626257
{
2626726258
old_card_survived_per_region[region_index] = survived_per_region[region_index] -

src/coreclr/gc/gcpriv.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3585,6 +3585,8 @@ class gc_heap
35853585
size_t* survived_per_region;
35863586
PER_HEAP
35873587
size_t* old_card_survived_per_region;
3588+
PER_HEAP_ISOLATED
3589+
size_t region_count;
35883590
#endif //USE_REGIONS
35893591

35903592
#define max_oom_history_count 4
@@ -5700,6 +5702,14 @@ class region_allocator
57005702
size_t get_free() { return (total_free_units * region_alignment) ; }
57015703
size_t get_region_alignment () { return region_alignment; }
57025704
size_t get_large_region_alignment () { return large_region_alignment; }
5705+
size_t get_used_region_count()
5706+
{
5707+
// currently we don't allocate anything from the right -
5708+
// once we do, we need a more sophisticated way to iterate
5709+
// through the used regions
5710+
assert (region_map_right_start == region_map_right_end);
5711+
return (region_map_left_end - region_map_left_start);
5712+
}
57035713
};
57045714
#endif //USE_REGIONS
57055715

0 commit comments

Comments
 (0)