The problem
While auditing #7633 I sabotaged layout_finish_deferred_boxed_object(ptr, saw_pointer) → (ptr, false) — i.e. every JSON-parsed record claims
POINTER_FREE while holding heap pointers. That is the stranded-live-child
hazard #7630's own soundness note names, and the exact failure the layout state
exists to prevent.
It produces byte-identical correct output under every instrument we have:
| probe |
plain |
ZEAL=1 PROTECT_FROMSPACE=1 |
FORCE_EVACUATE=1 |
| children also held in a separate array |
identical |
identical |
identical |
| children reachable ONLY via the record's slot |
identical |
identical |
identical |
The second probe was built specifically because the first was vacuous: 4,000
records × 2 pointer fields, 40 rounds of churn to force promotion, children read
back only after the churn, so the record's slot is the sole path to each string.
8 retired quarantine sets and 16 copying minors observed live — the
instruments were armed and the collector was moving.
Why this is not "the branch is safe"
The obvious benign explanation is refuted. Parse value strings are not
longlived or interned: string_storage_alloc (string/mod.rs:504) uses
arena_alloc_gc, the ordinary nursery arena — arena_alloc_gc_longlived is the
other function. My probe's strings are 6–10 chars, above
SHORT_STRING_MAX_LEN = 5, so they are real heap StringHeaders in the
nursery. They are collectable and movable, and a POINTER_FREE record should
therefore lose them.
So either the tracer does not honour POINTER_FREE on this path (in which case
the state's trace-skip is not buying what it claims anywhere), or something
re-marks these objects that neither I nor the PR author identified.
Why it matters
Every future change to layout-state bookkeeping — and #7630's family has more
queued — will cite "zeal + from-space protect: output identical" as evidence of
no stranded children. That sentence currently discriminates nothing: a
mutation guaranteed to strand children passes it. This is CLAUDE.md's hazard 4
(a gate that runs but whose subject never did), applied to the instrument rather
than the job.
#7633 merged on the strength of its argument — the materialiser owns each
object end-to-end, finalize is reached on every path (verified: zero early exits
between store and finalize in both parse functions), and the pointer case is
conservative — plus a clean gap suite. That was the right call. But the argument
is now the only thing holding it up, and the next such change may not have one
as tight.
What would close this
A probe where forcing POINTER_FREE on a pointer-bearing object faults or
corrupts. If one cannot be constructed, that is the finding: it means our
POINTER_FREE trace-skip is unobservable, and we should understand why before
building more optimizations on top of it. Either outcome is worth knowing, and
the probe becomes the regression test the whole family has been missing.
Starting points: check whether the full mark-sweep's conservative stack scan
(#7558) reaches these objects independently of their layout state; check whether
old-gen tracing consults _reserved layout bits at all after promotion; and try
a shape where the record is never promoted (small parse, forced minor only).
The problem
While auditing #7633 I sabotaged
layout_finish_deferred_boxed_object(ptr, saw_pointer)→(ptr, false)— i.e. every JSON-parsed record claimsPOINTER_FREEwhile holding heap pointers. That is the stranded-live-childhazard #7630's own soundness note names, and the exact failure the layout state
exists to prevent.
It produces byte-identical correct output under every instrument we have:
ZEAL=1 PROTECT_FROMSPACE=1FORCE_EVACUATE=1The second probe was built specifically because the first was vacuous: 4,000
records × 2 pointer fields, 40 rounds of churn to force promotion, children read
back only after the churn, so the record's slot is the sole path to each string.
8 retired quarantine sets and 16 copying minors observed live — the
instruments were armed and the collector was moving.
Why this is not "the branch is safe"
The obvious benign explanation is refuted. Parse value strings are not
longlived or interned:
string_storage_alloc(string/mod.rs:504) usesarena_alloc_gc, the ordinary nursery arena —arena_alloc_gc_longlivedis theother function. My probe's strings are 6–10 chars, above
SHORT_STRING_MAX_LEN = 5, so they are real heapStringHeaders in thenursery. They are collectable and movable, and a
POINTER_FREErecord shouldtherefore lose them.
So either the tracer does not honour
POINTER_FREEon this path (in which casethe state's trace-skip is not buying what it claims anywhere), or something
re-marks these objects that neither I nor the PR author identified.
Why it matters
Every future change to layout-state bookkeeping — and #7630's family has more
queued — will cite "zeal + from-space protect: output identical" as evidence of
no stranded children. That sentence currently discriminates nothing: a
mutation guaranteed to strand children passes it. This is CLAUDE.md's hazard 4
(a gate that runs but whose subject never did), applied to the instrument rather
than the job.
#7633 merged on the strength of its argument — the materialiser owns each
object end-to-end, finalize is reached on every path (verified: zero early exits
between store and finalize in both parse functions), and the pointer case is
conservative — plus a clean gap suite. That was the right call. But the argument
is now the only thing holding it up, and the next such change may not have one
as tight.
What would close this
A probe where forcing
POINTER_FREEon a pointer-bearing object faults orcorrupts. If one cannot be constructed, that is the finding: it means our
POINTER_FREEtrace-skip is unobservable, and we should understand why beforebuilding more optimizations on top of it. Either outcome is worth knowing, and
the probe becomes the regression test the whole family has been missing.
Starting points: check whether the full mark-sweep's conservative stack scan
(#7558) reaches these objects independently of their layout state; check whether
old-gen tracing consults
_reservedlayout bits at all after promotion; and trya shape where the record is never promoted (small parse, forced minor only).