Problem
The per-cycle valid-pointer set is a BTreeSet of every object in every arena (nursery + survivors + longlived + old) plus the malloc registry, rebuilt from scratch on every fallback minor and every full collection, then probed per traced edge.
- Structure:
gc/trace.rs:10-50
- Builder walks all 5 regions:
gc/trace.rs:285-342 (region list arena/walk.rs:119-141)
- Per-edge probes:
gc/trace.rs:481 and :410 (O(log n) after a range prefilter)
- Rebuilt each fallback minor + full:
gc/cycle.rs:1026-1039
On a 500 MB heap with ~4M objects this is roughly 0.4–1.5 s of BTreeSet insertion before marking even starts, and it scales with total heap — old-gen growth directly inflates minor pauses.
Proposed fix
Replace membership testing with the page-metadata classification the copying path already uses (gc/copying.rs:68-102 — classify_heap_space + plausible_gc_header), or a per-block object-start bitmap. Keep the BTree only for conservative interior-pointer floor lookups, which only the forced-conservative-scan path needs.
Context
Found by the 2026-07-09 GC audit (pause/scalability dimension). This is the single biggest latency lever in the collector: it dominates every fallback pause. Related: #6083 was closed after the debt-pacer rework, but the default (alloc-point) collection path still runs this builder synchronously.
Problem
The per-cycle valid-pointer set is a
BTreeSetof every object in every arena (nursery + survivors + longlived + old) plus the malloc registry, rebuilt from scratch on every fallback minor and every full collection, then probed per traced edge.gc/trace.rs:10-50gc/trace.rs:285-342(region listarena/walk.rs:119-141)gc/trace.rs:481and:410(O(log n) after a range prefilter)gc/cycle.rs:1026-1039On a 500 MB heap with ~4M objects this is roughly 0.4–1.5 s of BTreeSet insertion before marking even starts, and it scales with total heap — old-gen growth directly inflates minor pauses.
Proposed fix
Replace membership testing with the page-metadata classification the copying path already uses (
gc/copying.rs:68-102—classify_heap_space+plausible_gc_header), or a per-block object-start bitmap. Keep the BTree only for conservative interior-pointer floor lookups, which only the forced-conservative-scan path needs.Context
Found by the 2026-07-09 GC audit (pause/scalability dimension). This is the single biggest latency lever in the collector: it dominates every fallback pause. Related: #6083 was closed after the debt-pacer rework, but the default (alloc-point) collection path still runs this builder synchronously.