FA-90528 / Garbage collector invariants / Member archive
Card marking: cards rebuilt only for newly promoted objects · case 03
Old-to-young references recorded before a minor collection are forgotten afterwards.
Case contract
Two generations. objs maps id -> [generation, address, fields]; a field slot i of an old object lives at address + 8*i and belongs to card (slot address // 64). store writes a field and, when an old object receives a young reference, dirties that slot's card. minor: roots plus young referents of old slots in dirty cards seed a trace through young objects; unreached young objects are freed; survivors age by one and are promoted (addresses from 4096 in 64-byte steps) when age >= tenure; the card set is then rebuilt from every old slot that still references a young object. alloc id creates a young object with one null field; root/unroot edit the root list. Return per-minor {freed, promoted, cards}; following a freed object reports {"dangling": id}.
Why this case matters
Minor collections are only correct if the remembered set covers every old-to-young pointer.
One recorded failure
Sample boundary fixtureThis sample comes from the broken implementation of a controlled reproducer.
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: old-to-young edge survives two minor collections | [{"cards": [], "freed": [13, 14], "promoted": []}, {"cards": [], "freed": [11, 12], "promoted": []}] | [{"cards": [3], "freed": [13, 14], "promoted": []}, {"cards": [3], "freed": [], "promoted": []}] | Failed |
MEMBER ARCHIVE
The complete case is available to members.
This record includes three runnable implementations, regression fixtures, execution results, and source hashes.
Member access is invitation-based. Sign in with your invited account to inspect the sources.
Sign in to the archive ↗