@@ -13373,21 +13373,25 @@ void gc_heap::age_free_regions (const char* msg)
13373
13373
// though perhaps BGC can leave them there. Future work could verify and assert this.)
13374
13374
// b. Move any basic region in global_regions_to_decommit (which means we intended to decommit them
13375
13375
// but haven't done so yet) to surplus_regions
13376
- // b . Move all huge regions that are past the age threshold from global_free_huge_regions to aged_regions
13377
- // c . Move all basic/large regions that are past the age threshold from free_regions to aged_regions
13376
+ // c . Move all huge regions that are past the age threshold from global_free_huge_regions to aged_regions
13377
+ // d . Move all basic/large regions that are past the age threshold from free_regions to aged_regions
13378
13378
// 2. Move all regions from aged_regions to global_regions_to_decommit. Note that the intention is to
13379
13379
// combine this with move_highest_free_regions in a future change, which is why we don't just do this
13380
- // in steps 1b/1c .
13380
+ // in steps 1c/1d .
13381
13381
// 3. Compute the required per-heap budgets for SOH (basic regions) and the balance. The budget for LOH
13382
- // (large/huge ) is zero as we are using an entirely age-based approach.
13382
+ // (large) is zero as we are using an entirely age-based approach.
13383
13383
// balance = (number of free regions) - budget
13384
13384
// 4. Decide if we are going to distribute or decommit a nonzero balance. To distribute, we adjust the
13385
- // per-heap budgets, so after this step the LOH (large/huge) budgets can be positive.
13386
- // a. A negative balance (deficit) must be distributed since decommitting a negative number of regions
13387
- // doesn't make sense. A negative balance isn't possible for LOH since the budgets start at zero.
13385
+ // per-heap budgets, so after this step the LOH (large) budgets can be positive.
13386
+ // a. A negative balance (deficit) for SOH (basic) will be distributed it means we expect to use
13387
+ // more memory than we have on the free lists. A negative balance for LOH (large) isn't possible
13388
+ // for LOH since the budgets start at zero.
13388
13389
// b. For SOH (basic), we will decommit surplus regions unless we are in a foreground GC during BGC.
13389
- // c. For LOH (large/huge), we will distribute surplus regions since we are using an entirely age-based
13390
- // approach. However, if we are in a high-memory-usage scenario, we will decommit.
13390
+ // c. For LOH (large), we will distribute surplus regions since we are using an entirely age-based
13391
+ // approach. However, if we are in a high-memory-usage scenario, we will decommit. In this case,
13392
+ // we will also decommit the huge regions in global_free_huge_regions. Note that they were not
13393
+ // originally included in the balance because they are kept in a global list. Only basic/large
13394
+ // regions are kept in per-heap lists where they can be distributed.
13391
13395
// 5. Implement the distribute-or-decommit strategy. To distribute, we simply move regions across heaps,
13392
13396
// using surplus_regions as a holding space. To decommit, for server GC we generally leave them on the
13393
13397
// global_regions_to_decommit list and decommit them over time. However, in high-memory-usage scenarios,
@@ -13518,22 +13522,22 @@ void gc_heap::distribute_free_regions()
13518
13522
// if so, put the highest free regions on the decommit list
13519
13523
total_num_free_regions[kind] += surplus_regions[kind].get_num_free_regions();
13520
13524
13521
- ptrdiff_t balance = total_num_free_regions[kind] - total_budget_in_region_units[kind];
13525
+ ptrdiff_t balance_to_distribute = total_num_free_regions[kind] - total_budget_in_region_units[kind];
13522
13526
13523
- if (distribute_surplus_p(balance , kind, aggressive_decommit_large_p))
13527
+ if (distribute_surplus_p(balance_to_distribute , kind, aggressive_decommit_large_p))
13524
13528
{
13525
13529
#ifdef MULTIPLE_HEAPS
13526
13530
// we may have a deficit or - for large regions or if background GC is going on - a surplus.
13527
13531
// adjust the budget per heap accordingly
13528
- if (balance != 0)
13532
+ if (balance_to_distribute != 0)
13529
13533
{
13530
- dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance , free_region_kind_name[kind]));
13534
+ dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance_to_distribute , free_region_kind_name[kind]));
13531
13535
13532
13536
ptrdiff_t curr_balance = 0;
13533
13537
ptrdiff_t rem_balance = 0;
13534
13538
for (int i = 0; i < n_heaps; i++)
13535
13539
{
13536
- curr_balance += balance ;
13540
+ curr_balance += balance_to_distribute ;
13537
13541
ptrdiff_t adjustment_per_heap = curr_balance / n_heaps;
13538
13542
curr_balance -= adjustment_per_heap * n_heaps;
13539
13543
ptrdiff_t new_budget = (ptrdiff_t)heap_budget_in_region_units[kind][i] + adjustment_per_heap;
@@ -13577,20 +13581,28 @@ void gc_heap::distribute_free_regions()
13577
13581
}
13578
13582
else
13579
13583
{
13580
- assert (balance >= 0);
13584
+ assert (balance_to_distribute >= 0);
13585
+
13586
+ ptrdiff_t balance_to_decommit = balance_to_distribute;
13587
+ if (kind == large_free_region)
13588
+ {
13589
+ // huge regions aren't part of balance_to_distribute because they are kept in a global list
13590
+ // and therefore can't be distributed across heaps
13591
+ balance_to_decommit += global_free_huge_regions.get_size_free_regions() / global_region_allocator.get_large_region_alignment();
13592
+ }
13581
13593
13582
13594
dprintf(REGIONS_LOG, ("distributing the %zd %s regions, removing %zd regions",
13583
13595
total_budget_in_region_units[kind],
13584
13596
free_region_kind_name[kind],
13585
13597
balance));
13586
13598
13587
- if (balance > 0)
13599
+ if (balance_to_decommit > 0)
13588
13600
{
13589
13601
// remember how many regions we had on the decommit list already due to aging
13590
13602
size_t num_regions_to_decommit_before = global_regions_to_decommit[kind].get_num_free_regions();
13591
13603
13592
13604
// put the highest regions on the decommit list
13593
- global_region_allocator.move_highest_free_regions (balance * region_factor[kind],
13605
+ global_region_allocator.move_highest_free_regions (balance_to_decommit * region_factor[kind],
13594
13606
kind == basic_free_region,
13595
13607
global_regions_to_decommit);
13596
13608
@@ -13601,7 +13613,7 @@ void gc_heap::distribute_free_regions()
13601
13613
{
13602
13614
// we should now have 'balance' regions more on the decommit list
13603
13615
assert (global_regions_to_decommit[kind].get_num_free_regions() ==
13604
- num_regions_to_decommit_before + (size_t)balance );
13616
+ num_regions_to_decommit_before + (size_t)balance_to_decommit );
13605
13617
}
13606
13618
else
13607
13619
{
0 commit comments