Skip to content
62 changes: 32 additions & 30 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3744,17 +3744,6 @@ heap_segment* get_region_info_for_address (uint8_t* address)
return ((heap_segment*)(&seg_mapping_table[basic_region_index]));
}

// Go from the physical start of a region to its region info.
inline
heap_segment* get_region_info (uint8_t* region_start)
{
size_t region_index = (size_t)region_start >> gc_heap::min_segment_size_shr;
heap_segment* region_info_entry = (heap_segment*)&seg_mapping_table[region_index];
dprintf (REGIONS_LOG, ("region info for region %p is at %zd, %zx (alloc: %p)",
region_start, region_index, (size_t)region_info_entry, heap_segment_allocated (region_info_entry)));
return (heap_segment*)&seg_mapping_table[region_index];
}

// Go from the actual region info to its region start.
inline
uint8_t* get_region_start (heap_segment* region_info)
Expand All @@ -3769,6 +3758,17 @@ size_t get_region_size (heap_segment* region_info)
return (size_t)(heap_segment_reserved (region_info) - get_region_start (region_info));
}

// Go from the physical start of a region to its region info.
inline
heap_segment* get_region_info (uint8_t* region_start)
{
size_t region_index = (size_t)region_start >> gc_heap::min_segment_size_shr;
heap_segment* region_info_entry = (heap_segment*)&seg_mapping_table[region_index];
dprintf (REGIONS_LOG, ("region info for region %p is at %zd, %zx (size: %zx, alloc: %p)",
region_start, region_index, (size_t)region_info_entry, get_region_size(region_info_entry), heap_segment_allocated (region_info_entry)));
return (heap_segment*)&seg_mapping_table[region_index];
}

inline
size_t get_region_committed_size (heap_segment* region)
{
Expand Down Expand Up @@ -12983,7 +12983,7 @@ heap_segment* region_free_list::unlink_smallest_region (size_t minimum_size)
return smallest_region;
}

void region_free_list::transfer_regions (region_free_list* from)
void region_free_list::transfer_regions_from (region_free_list* from)
{
this->verify (this->num_free_regions == 0);
from->verify (from->num_free_regions == 0);
Expand Down Expand Up @@ -13215,7 +13215,7 @@ void gc_heap::distribute_free_regions()
#endif //MULTIPLE_HEAPS
if (settings.reason == reason_induced_aggressive)
{
global_regions_to_decommit[huge_free_region].transfer_regions (&global_free_huge_regions);
global_regions_to_decommit[huge_free_region].transfer_regions_from (&global_free_huge_regions);

#ifdef MULTIPLE_HEAPS
for (int i = 0; i < n_heaps; i++)
Expand All @@ -13227,7 +13227,7 @@ void gc_heap::distribute_free_regions()
#endif //MULTIPLE_HEAPS
for (int kind = basic_free_region; kind < count_free_region_kinds; kind++)
{
global_regions_to_decommit[kind].transfer_regions (&hp->free_regions[kind]);
global_regions_to_decommit[kind].transfer_regions_from (&hp->free_regions[kind]);
}
}
while (decommit_step(DECOMMIT_TIME_STEP_MILLISECONDS))
Expand Down Expand Up @@ -13281,7 +13281,7 @@ void gc_heap::distribute_free_regions()
{
// we may still have regions left on the regions_to_decommit list -
// use these to fill the budget as well
surplus_regions[kind].transfer_regions (&global_regions_to_decommit[kind]);
surplus_regions[kind].transfer_regions_from (&global_regions_to_decommit[kind]);
}
#ifdef MULTIPLE_HEAPS
for (int i = 0; i < n_heaps; i++)
Expand Down Expand Up @@ -13320,13 +13320,15 @@ void gc_heap::distribute_free_regions()
total_num_free_regions[kind] += region_list.get_num_free_regions();
}

global_free_huge_regions.transfer_regions (&hp->free_regions[huge_free_region]);
global_free_huge_regions.transfer_regions_from (&hp->free_regions[huge_free_region]);

heap_budget_in_region_units[i][basic_free_region] = 0;
min_heap_budget_in_region_units[i] = 0;
heap_budget_in_region_units[i][large_free_region] = 0;
}

dprintf (1, ("moved %2zd regions (%8zd) to decommit based on time", num_decommit_regions_by_time, size_decommit_regions_by_time));

for (int gen = soh_gen0; gen < total_generation_count; gen++)
{
if ((gen <= soh_gen2) &&
Expand Down Expand Up @@ -13365,9 +13367,7 @@ void gc_heap::distribute_free_regions()
}
}

dprintf (1, ("moved %2zd regions (%8zd) to decommit based on time", num_decommit_regions_by_time, size_decommit_regions_by_time));

global_free_huge_regions.transfer_regions (&global_regions_to_decommit[huge_free_region]);
global_free_huge_regions.transfer_regions_from (&global_regions_to_decommit[huge_free_region]);

size_t free_space_in_huge_regions = global_free_huge_regions.get_size_free_regions();

Expand All @@ -13388,12 +13388,13 @@ void gc_heap::distribute_free_regions()
{
num_regions_to_decommit[kind] = surplus_regions[kind].get_num_free_regions();

dprintf(REGIONS_LOG, ("%zd %s free regions, %zd regions budget, %zd regions on decommit list, %zd huge regions to consider",
dprintf(REGIONS_LOG, ("%zd %s free regions, %zd regions budget, %zd regions on decommit list, %zd huge region units (%zd young) to consider",
total_num_free_regions[kind],
kind_name[kind],
total_budget_in_region_units[kind],
num_regions_to_decommit[kind],
num_huge_region_units_to_consider[kind]));
num_huge_region_units_to_consider[kind],
num_young_huge_region_units_to_consider[kind]));

// check if the free regions exceed the budget
// if so, put the highest free regions on the decommit list
Expand All @@ -13407,7 +13408,7 @@ void gc_heap::distribute_free_regions()
#endif
(balance < 0))
{
dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance, kind_name[kind]));
dprintf (REGIONS_LOG, ("distributing the %zd %s region units deficit", -balance, kind_name[kind]));

#ifdef MULTIPLE_HEAPS
// we may have a deficit or - if background GC is going on - a surplus.
Expand All @@ -13433,7 +13434,7 @@ void gc_heap::distribute_free_regions()
rem_balance += new_budget - heap_budget_in_region_units[i][kind];
}
assert (rem_balance <= 0);
dprintf (REGIONS_LOG, ("remaining balance: %zd %s regions", rem_balance, kind_name[kind]));
dprintf (REGIONS_LOG, ("remaining balance: %zd %s region units", rem_balance, kind_name[kind]));

// if we have a left over deficit, distribute that to the heaps that still have more than the minimum
while (rem_balance < 0)
Expand All @@ -13443,7 +13444,7 @@ void gc_heap::distribute_free_regions()
size_t min_budget = (kind == basic_free_region) ? min_heap_budget_in_region_units[i] : 0;
if (heap_budget_in_region_units[i][kind] > min_budget)
{
dprintf (REGIONS_LOG, ("adjusting the budget for heap %d from %zd %s regions by %d to %zd",
dprintf (REGIONS_LOG, ("adjusting the budget for heap %d from %zd %s region units by %d to %zd",
i,
heap_budget_in_region_units[i][kind],
kind_name[kind],
Expand All @@ -13463,7 +13464,7 @@ void gc_heap::distribute_free_regions()
else
{
num_regions_to_decommit[kind] = balance;
dprintf(REGIONS_LOG, ("distributing the %zd %s regions, removing %zd regions",
dprintf(REGIONS_LOG, ("distributing the %zd %s region units, removing %zd region units",
total_budget_in_region_units[kind],
kind_name[kind],
num_regions_to_decommit[kind]));
Expand All @@ -13489,8 +13490,9 @@ void gc_heap::distribute_free_regions()
}
else
{
dprintf (REGIONS_LOG, ("Moved %zd %s regions to decommit list",
global_regions_to_decommit[huge_free_region].get_num_free_regions(), kind_name[huge_free_region]));
dprintf (REGIONS_LOG, ("Moved %zd %s regions (%zd units) to decommit list",
global_regions_to_decommit[huge_free_region].get_num_free_regions(), kind_name[huge_free_region],
(global_regions_to_decommit[huge_free_region].get_size_free_regions() / region_size[kind])));

// cannot assert we moved any regions because there may be a single huge region with more than we want to decommit
}
Expand Down Expand Up @@ -13545,7 +13547,7 @@ void gc_heap::distribute_free_regions()
if (surplus_regions[kind].get_num_free_regions() > 0)
{
assert (!"should have exhausted the surplus_regions");
global_regions_to_decommit[kind].transfer_regions (&surplus_regions[kind]);
global_regions_to_decommit[kind].transfer_regions_from (&surplus_regions[kind]);
}
}

Expand Down Expand Up @@ -13580,7 +13582,7 @@ void gc_heap::distribute_free_regions()
{
if (global_regions_to_decommit[kind].get_num_free_regions() != 0)
{
free_regions[kind].transfer_regions (&global_regions_to_decommit[kind]);
free_regions[kind].transfer_regions_from (&global_regions_to_decommit[kind]);
}
}
#endif //MULTIPLE_HEAPS
Expand Down Expand Up @@ -26004,7 +26006,7 @@ bool gc_heap::change_heap_count (int new_n_heaps)

for (int kind = 0; kind < count_free_region_kinds; kind++)
{
hpd->free_regions[kind].transfer_regions(&hp->free_regions[kind]);
hpd->free_regions[kind].transfer_regions_from (&hp->free_regions[kind]);
}
}
dprintf (9999, ("h%d changing %d->%d", heap_number, n_heaps, new_n_heaps));
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ class region_free_list
void reset();
void add_region_front (heap_segment* region);
void add_region_in_descending_order (heap_segment* region_to_add);
void transfer_regions (region_free_list* from);
void transfer_regions_from (region_free_list* from);
heap_segment* unlink_region_front();
heap_segment* unlink_smallest_region (size_t size);
size_t get_num_free_regions();
Expand Down