Skip to content

GC: copying minor reports not_attempted on every cycle in the memory-stability gates; old_page_forced_defrag moved > selected #9659

Description

@proggeramlug

Summary

compile-smoke's step 14 (./scripts/run_memory_stability_tests.sh) fails two GC gates. Both are architectural assertions that the copying minor actually did work — the #7025 class of "a gate must assert its subject was live".

Run: 33743461798 (job compile-smoke), evidence artifact gc-evidence-Linux (id 9914097984).

1. The copying minor is never attempted

Five workloads report every cycle as not_attempted, with zero bytes moved:

workload cycles not_attempted copied promoted moved
default_copying 8 8 0 0 0
string_heavy 4 4 0 0 0
closure_heavy 5 5 0 0 0
large_object_barriers 4 4 0 0 0
raw_numeric_layouts 3 3 0 0 0

Critically, this is not a declined copy. Every other fallback reason is zero:

none=0  copy_only_roots=0  barriers_inactive=0  conservative_stack=0
malloc_registry_unavailable=0  pinned_young_root=0
pinned_young_dirty_slot=0  pinned_young_transitive=0
not_attempted=8

conservative_stack.scan_bytes = 0, truncated_cycles = 0, unbounded_cycles = 0 — so the usual "a conservative scan made the copying minor ineligible" explanation does not apply here. The minor path appears not to be entered at all.

large_object_barriers additionally reports missing large-object exclusion telemetry.

2. old_page_forced_defrag: moved more than was selected

old_page_forced_defrag:5: evacuation.old_page_moved_bytes(80)
                        > evacuation_policy.old_page_selected_live_bytes(32)

That workload does run (copy_only_roots=1, moved_bytes=80), so this is an accounting inconsistency rather than an inactive path.

Why this surfaced now

This gate runs in exactly one place — test.yml:2837, inside compile-smoke, which only runs in the full tier. The last two release cycles (runs 33626738093, 33709074616) both failed at step 8 (Compile all test files) and never reached step 14. With step 8 fixed, step 14 executed for the first time in months.

So this is almost certainly pre-existing and was dark, not a regression introduced by the release candidate. The scripts were last touched by 41e8479a56 ("clear r21 full-suite blockers", 2026-08-27), which suggests they last passed around then.

What still passes

Everything else in the step is green, including the workloads that exercise real behaviour: all canaries, raw numeric object field semantics, and the [gc-trace] workloads json_roundtrip, string_churn, object_property_churn, mixed_request_shaping, map_set_churn, promise_churn. gc-stress (all legs) and gc-ratchet pass in the same tier.

So the failing assertions are about whether the copying minor was exercised, not about observed incorrect behaviour.

Ask

Is not_attempted on every cycle expected for these workloads in CI (e.g. they never reach the nursery pressure that triggers a moving minor), or has the moving-minor path stopped being entered? The former means the gate needs a liveness precondition; the latter is a real architectural regression.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions