Skip to content

[gc] Graduate incremental collection: budgeted scanner coverage, assists for all phases, default-on (successor to #6083) #6180

Description

@proggeramlug

Problem

Automatic collections in compiled programs are synchronous, unbounded, alloc-point STW cycles because the budgeted (incremental) machinery is structurally unreachable:

  1. ~50 of ~57 registered root scanners have no budgeted step form, and any unbudgeted scanner blocks the sliced stepper: predicate gc/roots.rs:286-307, registrations gc/mod.rs:289-454.
  2. The alloc-point direct arm (gc/policy.rs:1232-1284) forces the conservative scan (:1254), which makes the copying fast path ineligible (gc/copying.rs:769-774) — so the collection lands in GcCycleState::new_minor_fallback(...).run_to_completion() with an unbounded budget (gc/cycle.rs:1002-1009).
  3. PERRY_GC_INCREMENTAL=1 exists but is off by default and has a runaway hole: mutator assists only advance 4 phases (gc/cycle.rs:47-55, gc/policy.rs:1772-1778), so a compute loop that never reaches the event pump parks a cycle at the sweep boundary indefinitely with the incremental-mark barrier still enabled (gc/cycle.rs:1041-1044) → unbounded RSS.

Proposed fix (staged)

  1. Convert the ~15 highest-traffic scanners to budgeted form (runtime handles, promise, timer, class/symbol tables already are; object caches, descriptor tables, closure caches, error props, fs/process tables are not).
  2. Let mutator assists drive all resumable phases (sweep is already sliced), or add a debt cap that escalates to a synchronous finish — GcDebtSnapshot (gc/telemetry.rs:446-468) already measures exactly this but is telemetry-only.
  3. Graduate PERRY_GC_INCREMENTAL to default-on once 1+2 land.
  4. Route alloc-point trigger crossings to the pump-boundary moving minor via the existing deferral flag (gc/policy.rs:1246-1251) by default once loop-poll coverage lands.

Context

2026-07-09 GC audit. Successor to #6083, whose closure shipped the trigger re-arm fix and the off-by-default incremental mode but left the default path fully STW.

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