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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions