Skip to content

[release/10.0] Redo GC heap size fix in heavily pinning scenarios#127573

Open
janvorli wants to merge 3 commits intodotnet:release/10.0from
janvorli:backport-redo-pinning-fix
Open

[release/10.0] Redo GC heap size fix in heavily pinning scenarios#127573
janvorli wants to merge 3 commits intodotnet:release/10.0from
janvorli:backport-redo-pinning-fix

Conversation

@janvorli
Copy link
Copy Markdown
Member

@janvorli janvorli commented Apr 29, 2026

Backport of #126043 to release/10.0

Customer Impact

  • Customer reported
  • Found internally

This change puts back the recently reverted fix for the GC heap size
regression with regions when there is heavy pinning.

It also fixes the issue due to which the change was recently reverted
in .NET 10. The issue was in allocate_in_condemned_generations where a very
large plug could never be relocated into a new region because front padding
was always added, which could lead to an infinite loop.

Regression

  • Yes, introduced in .NET 10
  • No

Testing

CI tests, local testing using regression test, GC perf tests

Risk

Low, the change is limited to the relocation logic for very large plugs in
heavily pinning scenarios and preserves the existing behavior everywhere else.

Backport of dotnet#126043 to release/10.0

- [x] Customer reported
- [ ] Found internally

This change puts back the recently reverted fix for the GC heap size
regression with regions when there is heavy pinning.

It also fixes the issue due to which the change was recently reverted
in .NET 10. The issue was in `allocate_in_condemned_generations` where a very
large plug could never be relocated into a new region because front padding
was always added, which could lead to an infinite loop.

- [x] Yes, introduced in .NET 10

CI tests, local testing using regression test, GC perf tests

Low, the change is limited to the relocation logic for very large plugs in
heavily pinning scenarios and preserves the existing behavior everywhere else.
@janvorli janvorli added this to the 10.0.x milestone Apr 29, 2026
@janvorli janvorli requested a review from VSadov April 29, 2026 17:20
@janvorli janvorli self-assigned this Apr 29, 2026
Copilot AI review requested due to automatic review settings April 29, 2026 17:20
@janvorli janvorli added Servicing-consider Issue for next servicing release review area-GC-coreclr labels Apr 29, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Backport to release/10.0 that reintroduces the GC regions heap-size regression fix for heavily pinning scenarios, while addressing the previously reverted hang risk by ensuring near-region-sized plugs can still be relocated (avoiding an infinite retry loop).

Changes:

  • Adds logic in allocate_in_condemned_generations to skip front padding for near-region-sized plugs so relocation can succeed in empty regions.
  • Refactors pinned-allocation attribution into helper(s) and introduces a shared heuristic (decide_on_gen1_pin_promotion) used by both regions and non-regions paths.
  • Updates regions planning logic to treat “large pins” specially (avoid demoting them to gen0) and threads promotion decisions via decide_on_demotion_pin_surv.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
src/coreclr/gc/gcpriv.h Updates GC heap APIs/fields to support new pin promotion/demotion decisions and pinned-allocation attribution helpers.
src/coreclr/gc/gc.cpp Implements the relocation/padding fix, new pin-promotion heuristics, refactors pinned-allocation accounting, and updates region planning/demotion decisions for large pins.

Comment thread src/coreclr/gc/gc.cpp Outdated
Comment thread src/coreclr/gc/gc.cpp Outdated
Comment thread src/coreclr/gc/gc.cpp Outdated
Comment thread src/coreclr/gc/gc.cpp
Comment thread src/coreclr/gc/gc.cpp Outdated
Copilot AI review requested due to automatic review settings May 4, 2026 21:02
@janvorli janvorli force-pushed the backport-redo-pinning-fix branch from 44b8269 to f3ae47b Compare May 4, 2026 21:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

Comment thread src/coreclr/gc/gc.cpp
Comment on lines +32583 to +32586
if (!heap_segment_swept_in_plan (current_region))
{
gen1_pins_left += heap_segment_pinned_survived (current_region);
total_space_to_skip += get_region_size (current_region);
Comment thread src/coreclr/gc/gc.cpp

maxgen_pinned_compact_before_advance = generation_pinned_allocation_compact_size (generation_of (max_generation));

bool large_pins_p = false;
Comment thread src/coreclr/gc/gc.cpp
Comment on lines 32705 to +32707
if (current_region)
{
decide_on_demotion_pin_surv (current_region, &to_be_empty_regions);
decide_on_demotion_pin_surv (current_region, &to_be_empty_regions, actual_promote_gen1_pins_p, large_pins_p);
Comment thread src/coreclr/gc/gc.cpp
Comment on lines +20859 to +20866
// A near-region-sized plug can't fit with front padding even in an empty region, so skip the padding.
// This is safe because front padding only exists to protect short plugs (shorter than sizeof(plug_and_gap))
// from being overwritten by the plug_and_gap header during compaction — a plug this large is in no such danger.
if ((pad_in_front & USE_PADDING_FRONT) &&
(size + Align (min_obj_size) >
((size_t)1 << min_segment_size_shr) - sizeof (aligned_plug_and_gap)))
{
pad_in_front = 0;
Comment thread src/coreclr/gc/gc.cpp
Comment on lines +32347 to 32354
if (!promote_pins_p && (gen_num == (max_generation - 1)) && promote_gen1_pins_p)
{
promote_pins_p = true;
}

if (promote_pins_p)
{
new_gen_num = get_plan_gen_num (heap_segment_gen_num (region));
@rbhanda rbhanda modified the milestones: 10.0.x, 10.0.9 May 4, 2026
@JulieLeeMSFT JulieLeeMSFT added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels May 5, 2026
@JulieLeeMSFT
Copy link
Copy Markdown
Member

No merge yet. Waiting for more testing. Also the author needs to check build failures and resolve comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-GC-coreclr NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants