@@ -13373,21 +13373,25 @@ void gc_heap::age_free_regions (const char* msg)
1337313373//       though perhaps BGC can leave them there.  Future work could verify and assert this.)
1337413374//    b. Move any basic region in global_regions_to_decommit (which means we intended to decommit them
1337513375//       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
1337813378// 2. Move all regions from aged_regions to global_regions_to_decommit.  Note that the intention is to
1337913379//    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 .
1338113381// 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.
1338313383//        balance = (number of free regions) - budget
1338413384// 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.
1338813389//    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.
1339113395// 5. Implement the distribute-or-decommit strategy.  To distribute, we simply move regions across heaps,
1339213396//    using surplus_regions as a holding space.  To decommit, for server GC we generally leave them on the
1339313397//    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()
1351813522        // if so, put the highest free regions on the decommit list
1351913523        total_num_free_regions[kind] += surplus_regions[kind].get_num_free_regions();
1352013524
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];
1352213526
13523-         if (distribute_surplus_p(balance , kind, aggressive_decommit_large_p))
13527+         if (distribute_surplus_p(balance_to_distribute , kind, aggressive_decommit_large_p))
1352413528        {
1352513529#ifdef MULTIPLE_HEAPS
1352613530            // we may have a deficit or - for large regions or if background GC is going on - a surplus.
1352713531            // adjust the budget per heap accordingly
13528-             if (balance  != 0)
13532+             if (balance_to_distribute  != 0)
1352913533            {
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]));
1353113535
1353213536                ptrdiff_t curr_balance = 0;
1353313537                ptrdiff_t rem_balance = 0;
1353413538                for (int i = 0; i < n_heaps; i++)
1353513539                {
13536-                     curr_balance += balance ;
13540+                     curr_balance += balance_to_distribute ;
1353713541                    ptrdiff_t adjustment_per_heap = curr_balance / n_heaps;
1353813542                    curr_balance -= adjustment_per_heap * n_heaps;
1353913543                    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()
1357713581        }
1357813582        else
1357913583        {
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+             }
1358113593
1358213594            dprintf(REGIONS_LOG, ("distributing the %zd %s regions, removing %zd regions",
1358313595                total_budget_in_region_units[kind],
1358413596                free_region_kind_name[kind],
1358513597                balance));
1358613598
13587-             if (balance  > 0)
13599+             if (balance_to_decommit  > 0)
1358813600            {
1358913601                // remember how many regions we had on the decommit list already due to aging
1359013602                size_t num_regions_to_decommit_before = global_regions_to_decommit[kind].get_num_free_regions();
1359113603
1359213604                // 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],
1359413606                                                                   kind == basic_free_region,
1359513607                                                                   global_regions_to_decommit);
1359613608
@@ -13601,7 +13613,7 @@ void gc_heap::distribute_free_regions()
1360113613                {
1360213614                    // we should now have 'balance' regions more on the decommit list
1360313615                    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 );
1360513617                }
1360613618                else
1360713619                {
0 commit comments