@@ -13338,6 +13338,49 @@ void gc_heap::age_free_regions (const char* msg)
13338
13338
}
13339
13339
}
13340
13340
13341
+ // distribute_free_regions is called during all blocking GCs and in the start of the BGC mark phase
13342
+ // unless we already called it during an ephemeral GC right before the BGC.
13343
+ //
13344
+ // Free regions are stored on the following permanent lists:
13345
+ // - global_regions_to_decommit
13346
+ // - global_free_huge_regions
13347
+ // - (per-heap) free_regions
13348
+ // and the following lists that are local to distribute_free_regions:
13349
+ // - aged_regions
13350
+ // - surplus_regions
13351
+ //
13352
+ // For reason_induced_aggressive GCs, we decommit all regions. Therefore, the below description is
13353
+ // for other GC types.
13354
+ //
13355
+ // distribute_free_regions steps:
13356
+ //
13357
+ // 1. Process region ages
13358
+ // a. Move all huge regions from free_regions to global_free_huge_regions.
13359
+ // (The intention is that free_regions shouldn't contain any huge regions outside of the period
13360
+ // where a GC reclaims them and distribute_free_regions moves them to global_free_huge_regions,
13361
+ // though perhaps BGC can leave them there. Future work could verify and assert this.)
13362
+ // b. Move any basic region in global_regions_to_decommit (which means we intended to decommit them
13363
+ // but haven't done so yet) to surplus_regions
13364
+ // b. Move all huge regions that are past the age threshold from global_free_huge_regions to aged_regions
13365
+ // c. Move all basic/large regions that are past the age threshold from free_regions to aged_regions
13366
+ // 2. Move all regions from aged_regions to global_regions_to_decommit. Note that the intention is to
13367
+ // combine this with move_highest_free_regions in a future change, which is why we don't just do this
13368
+ // in steps 1b/1c.
13369
+ // 3. Compute the required per-heap budgets for SOH (basic regions) and the balance. The budget for LOH
13370
+ // (large/huge) is zero as we are using an entirely age-based approach.
13371
+ // balance = (number of free regions) - budget
13372
+ // 4. Decide if we are going to distribute or decommit a nonzero balance. To distribute, we adjust the
13373
+ // per-heap budgets, so after this step the LOH (large/huge) budgets can be positive.
13374
+ // a. A negative balance (deficit) must be distributed since decommitting a negative number of regions
13375
+ // doesn't make sense. A negative balance isn't possible for LOH since the budgets start at zero.
13376
+ // b. For SOH (basic), we will decommit surplus regions unless we are in a foreground GC during BGC.
13377
+ // c. For LOH (large/huge), we will distribute surplus regions since we are using an entirely age-based
13378
+ // approach. However, if we are in a high-memory-usage scenario, we will decommit.
13379
+ // 5. Implement the distribute-or-decommit strategy. To distribute, we simply move regions across heaps,
13380
+ // using surplus_regions as a holding space. To decommit, for server GC we generally leave them on the
13381
+ // global_regions_to_decommit list and decommit them over time. However, in high-memory-usage scenarios,
13382
+ // we will immediately decommit some or all of these regions. For workstation GC, we decommit a limited
13383
+ // amount and move the rest back to the (one) heap's free_list.
13341
13384
void gc_heap::distribute_free_regions()
13342
13385
{
13343
13386
#ifdef MULTIPLE_HEAPS
0 commit comments