Skip to content

Commit

Permalink
Optimize region count (#56471)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PeterSolMS authored Jul 30, 2021
1 parent 5089894 commit bf83d79
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 13 deletions.
17 changes: 4 additions & 13 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,7 @@ bool affinity_config_specified_p = false;
#ifdef USE_REGIONS
region_allocator global_region_allocator;
uint8_t*(*initial_regions)[total_generation_count][2] = nullptr;
size_t gc_heap::region_count = 0;
#endif //USE_REGIONS

#ifdef BACKGROUND_GC
Expand Down Expand Up @@ -3512,12 +3513,6 @@ size_t get_basic_region_index_for_address (uint8_t* address)
return (basic_region_index - ((size_t)g_gc_lowest_address >> gc_heap::min_segment_size_shr));
}

inline
size_t get_total_region_count()
{
return (get_basic_region_index_for_address (g_gc_highest_address) + 1);
}

// Go from a random address to its region info. The random address could be
// in one of the basic regions of a larger region so we need to check for that.
inline
Expand Down Expand Up @@ -9741,7 +9736,6 @@ size_t gc_heap::sort_mark_list()

#ifdef USE_REGIONS
// first set the pieces for all regions to empty
size_t region_count = get_total_region_count();
assert (g_mark_list_piece_size >= region_count);
for (size_t region_index = 0; region_index < region_count; region_index++)
{
Expand Down Expand Up @@ -21140,7 +21134,6 @@ size_t gc_heap::get_promoted_bytes()
}

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

#ifdef USE_REGIONS
special_sweep_p = false;
region_count = global_region_allocator.get_used_region_count();
grow_mark_list_piece();
#endif //USE_REGIONS

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

void gc_heap::grow_mark_list_piece()
{
size_t region_count = get_total_region_count();
if (g_mark_list_piece_size < region_count)
{
delete[] g_mark_list_piece;
Expand All @@ -26240,11 +26233,10 @@ void gc_heap::save_current_survived()
{
if (!survived_per_region) return;

size_t region_info_to_copy = get_total_region_count() * sizeof (size_t);
size_t region_info_to_copy = region_count * sizeof (size_t);
memcpy (old_card_survived_per_region, survived_per_region, region_info_to_copy);

#ifdef _DEBUG
size_t region_count = get_total_region_count();
for (size_t region_index = 0; region_index < region_count; region_index++)
{
if (survived_per_region[region_index] != 0)
Expand All @@ -26261,7 +26253,6 @@ void gc_heap::update_old_card_survived()
{
if (!survived_per_region) return;

size_t region_count = get_total_region_count();
for (size_t region_index = 0; region_index < region_count; region_index++)
{
old_card_survived_per_region[region_index] = survived_per_region[region_index] -
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -3585,6 +3585,8 @@ class gc_heap
size_t* survived_per_region;
PER_HEAP
size_t* old_card_survived_per_region;
PER_HEAP_ISOLATED
size_t region_count;
#endif //USE_REGIONS

#define max_oom_history_count 4
Expand Down Expand Up @@ -5700,6 +5702,14 @@ class region_allocator
size_t get_free() { return (total_free_units * region_alignment) ; }
size_t get_region_alignment () { return region_alignment; }
size_t get_large_region_alignment () { return large_region_alignment; }
size_t get_used_region_count()
{
// currently we don't allocate anything from the right -
// once we do, we need a more sophisticated way to iterate
// through the used regions
assert (region_map_right_start == region_map_right_end);
return (region_map_left_end - region_map_left_start);
}
};
#endif //USE_REGIONS

Expand Down

0 comments on commit bf83d79

Please sign in to comment.