Parent: #473 Follows: #556, #558, #1001, #1002
Measured problem
The clean real-GC ReleaseFast matrix at 8ca0d15b preserves every frozen checksum but leaves the two structure controls far behind system JavaScriptCore:
representative_json_stringify_depth_4096: 1163.341 ms versus 111.120 ms (10.47x elapsed gap), checksum83848800;representative_json_stringify_shallow_4096: 966.656 ms versus 104.796 ms (9.22x elapsed gap), checksum63340200.
Those are seven fresh-process, order-balanced pairs with both medians above 50 ms. Raw evidence and exact binary/source/dependency hashes are in docs/.data/json-jit-pipeline-jsc-2026-10-01.json; the dated report is docs/.data/json-jit-pipeline-jsc-2026-10-01.md.
A separate five-second macOS sample capture of the exact deep runner recorded 3,005 main-thread samples. The call graph repeatedly cycles through four binary offsets; each appears about 1,564–1,569 times when recursive frames are counted. Source inspection identifies the corresponding semantic cycle as Stringifier.serializeProperty → serializeLoaded → serializeObject → serializeObjectEntry → serializeProperty for every object level. This mapping is an inference because the ReleaseFast binary does not retain function-level symbols. The sampler completed before the bounded wrapper stopped the runner during symbol-processing memory growth, so the capture is attribution only; all timing and correctness claims come from the completed matrix above.
Scope
- Replace recursive ordinary array/object traversal with an explicit, allocator-bounded serialization frame stack.
- Preserve the exact SerializeJSONProperty ordering: live
Get,toJSON, replacer call, wrapper unboxing, cycle entry/leave, key snapshot, and output emission/rollback. - Preserve active-ancestor cycle semantics without turning legal shared siblings into cycles.
- Preserve Proxy/accessor/host-exotic fallbacks, mutation between sibling callbacks, property order, indentation,
undefinedomission versus arraynull, BigInt throws, and the existing logical/native depth contract. - Keep the completed output transfer and temporary-allocator ownership exact under moving GC, OOM, and no-GIL execution.
- Profile the shallow shared-sibling row separately from the deep chain so one improvement cannot hide a regression in the other.
Acceptance
- Focused tests cover deep objects, deep arrays, shallow shared siblings, aliases, cycles, getters, Proxy traps,
toJSON, replacers, indentation, omission rollback, BigInt, and abrupt completion order. - The 50,000-level deep witnesses still throw catchable
RangeErrorin tree and required-VM modes; allocation-failure sweeps leave no partial state or leak. - JSON test262, tree/required-VM agreement, real-GC moving collection, no-GIL, and TSan gates remain exact.
- Seven-pair exact-parent evidence shows stable lower CPU work on both depth-4096 and shallow-4096 rows, with base/variant/reviver/escaped controls and exact checksums.
- A fresh seven-pair direct-JSC matrix materially narrows both 10.47x/9.22x gaps without changing jobs, warmup, timed boundary, or output.
Guardrails
No source/workload recognition, reduced nesting, cached final JSON, omitted callback/Get work, global visited set, looser stack limit, changed checksum, arena-only shortcut, or benchmark-specific branch.