Skip to content

GC layout fast path skips pointer slots at index ≥ 49 on SIDE_MASK objects (trace + root scans) #6495

Description

@proggeramlug

Found while instrumenting the GC for an unrelated live-sweep bug (#6494 diagnostics).

An env-gated invariant probe inside visit_overflow_field_slots_mut's layout fast path — "when layout_visit_pointer_slots_for_user reports a usable layout, every pointer-bearing overflow slot must be among the visited indexes" — fired ~3,200 times per run on a large compiled TUI app, across 17 distinct owners:

OVF-LAYOUT-MISS owner=0x44b67eed7e0 idx=49 val=0x7ffd0... visited=49 layout=[state=SIDE_MASK allp=false mask=0x1ffffffffffff]
OVF-LAYOUT-MISS owner=0x44b67eed7e0 idx=50 val=0x7ffd0... visited=49 layout=[state=SIDE_MASK allp=false mask=0x1ffffffffffff]
... (uniform across idx 49..63 for every affected owner)
  • state=SIDE_MASK, mask=0x1ffffffffffff = bits 0..=48 set — the mask claims slots ≥ 49 are pointer-free while the overflow Vec actually holds NaN-boxed heap pointers there (0x7ffd...).
  • LayoutSlotMask::Inline(u64) can represent slots up to 63, so the cap at bit 48 is not the inline-mask width; either layout_note_slot never ran for those writes (a store path that bypasses the note for indexes ≥ 49?) or the notes were dropped.
  • Consequence: the mark-phase trace and the GC root scans that use the layout fast path skip those slots entirely. Any object reachable only through slot ≥ 49 of an affected owner is unmarked and swept live — same failure class as fix(gc): allocate-black births were never traced — children reachable only through them were swept live #6494, different mechanism.

Repro context: objects with 50+ overflow fields (large config/props-style dictionaries) inside a big esbuild bundle; the probe fires steadily during normal operation. Happy to share the probe diff — it is ~20 lines inside visit_overflow_field_slots_mut, gated on an env var.

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