Skip to content

[perf] GC valid-pointer set is a full-heap BTreeSet rebuilt per cycle — replace with page-metadata classification #6179

Description

@proggeramlug

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-102classify_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.

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