Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 65 additions & 72 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13414,86 +13414,25 @@ void gc_heap::distribute_free_regions()
num_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
// if so, consider putting the highest free regions on the decommit list
total_num_free_regions[kind] += num_regions_to_decommit[kind];

ptrdiff_t balance = total_num_free_regions[kind] + num_huge_region_units_to_consider[kind] - total_budget_in_region_units[kind];

// Ignore young huge regions if they are contributing to a surplus.
if (balance > 0)
{
if (balance > static_cast<ptrdiff_t>(num_young_huge_region_units_to_consider[kind]))
{
balance -= num_young_huge_region_units_to_consider[kind];
}
else
{
balance = 0;
}
}

if (
// first check if we should decommit any regions
if ((balance > 0)
#ifdef BACKGROUND_GC
(background_running_p() && (settings.condemned_generation != max_generation)) ||
&& (!background_running_p() || (settings.condemned_generation == max_generation))
#endif
(balance < 0))
)
{
dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance, kind_name[kind]));
// ignore young huge regions when determining how much to decommit
num_regions_to_decommit[kind] =
max(static_cast<ptrdiff_t>(0),
(balance - static_cast<ptrdiff_t>(num_young_huge_region_units_to_consider[kind])));

balance -= num_regions_to_decommit[kind];

#ifdef MULTIPLE_HEAPS
// we may have a deficit or - if background GC is going on - a surplus.
// adjust the budget per heap accordingly
if (balance != 0)
{
ptrdiff_t curr_balance = 0;
ptrdiff_t rem_balance = 0;
for (int i = 0; i < n_heaps; i++)
{
curr_balance += balance;
ptrdiff_t adjustment_per_heap = curr_balance / n_heaps;
curr_balance -= adjustment_per_heap * n_heaps;
ptrdiff_t new_budget = (ptrdiff_t)heap_budget_in_region_units[i][kind] + adjustment_per_heap;
ptrdiff_t min_budget = (kind == basic_free_region) ? (ptrdiff_t)min_heap_budget_in_region_units[i] : 0;
dprintf (REGIONS_LOG, ("adjusting the budget for heap %d from %zd %s regions by %zd to %zd",
i,
heap_budget_in_region_units[i][kind],
kind_name[kind],
adjustment_per_heap,
max (min_budget, new_budget)));
heap_budget_in_region_units[i][kind] = max (min_budget, new_budget);
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]));

// if we have a left over deficit, distribute that to the heaps that still have more than the minimum
while (rem_balance < 0)
{
for (int i = 0; i < n_heaps; i++)
{
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",
i,
heap_budget_in_region_units[i][kind],
kind_name[kind],
-1,
heap_budget_in_region_units[i][kind] - 1));

heap_budget_in_region_units[i][kind] -= 1;
rem_balance += 1;
if (rem_balance == 0)
break;
}
}
}
}
#endif //MULTIPLE_HEAPS
}
else
{
num_regions_to_decommit[kind] = balance;
dprintf(REGIONS_LOG, ("distributing the %zd %s regions, removing %zd regions",
total_budget_in_region_units[kind],
kind_name[kind],
Expand Down Expand Up @@ -13527,6 +13466,60 @@ void gc_heap::distribute_free_regions()
}
}
}

#ifdef MULTIPLE_HEAPS
if (balance != 0)
{
dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance, kind_name[kind]));

// we may have a deficit or - if background GC is going on - a surplus.
// adjust the budget per heap accordingly

ptrdiff_t curr_balance = 0;
ptrdiff_t rem_balance = 0;
for (int i = 0; i < n_heaps; i++)
{
curr_balance += balance;
ptrdiff_t adjustment_per_heap = curr_balance / n_heaps;
curr_balance -= adjustment_per_heap * n_heaps;
ptrdiff_t new_budget = (ptrdiff_t)heap_budget_in_region_units[i][kind] + adjustment_per_heap;
ptrdiff_t min_budget = (kind == basic_free_region) ? (ptrdiff_t)min_heap_budget_in_region_units[i] : 0;
dprintf (REGIONS_LOG, ("adjusting the budget for heap %d from %zd %s regions by %zd to %zd",
i,
heap_budget_in_region_units[i][kind],
kind_name[kind],
adjustment_per_heap,
max (min_budget, new_budget)));
heap_budget_in_region_units[i][kind] = max (min_budget, new_budget);
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]));

// if we have a left over deficit, distribute that to the heaps that still have more than the minimum
while (rem_balance < 0)
{
for (int i = 0; i < n_heaps; i++)
{
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",
i,
heap_budget_in_region_units[i][kind],
kind_name[kind],
-1,
heap_budget_in_region_units[i][kind] - 1));

heap_budget_in_region_units[i][kind] -= 1;
rem_balance += 1;
if (rem_balance == 0)
break;
}
}
}
}
#endif
}

for (int kind = basic_free_region; kind < kind_count; kind++)
Expand Down