Parent: #480 Related: #473, #941 Follows: #1022
Executed evidence
On exact main 2723311b, a temporary same-module witness drove the production Array.prototype.join / toLocaleString entry and unwind paths. The probe was removed after collection.
ArrayJoinActive is 32 bytes and each RuntimeObjectIdentity slot is 16 bytes. After every completed or caught invocation, logical length returned to zero but allocator capacity remained:
- shallow
[1, 2].join("-"): capacity 9, retaining 176 logical bytes; - successful 40-level nested join: capacity 44, retaining 736 logical bytes;
- successful 20-level nested
toLocaleString: still capacity 44 / 736 bytes; - self/mutual cycles and aliases: length 0, capacity 44 after unwind;
- throwing element
toString, followed by successful retry: length 0, capacity 44 after unwind.
The owner and vector currently allocate from the realm arena. Interpreter.deinit does not reclaim either, and the active-set pointer dies with the temporary interpreter, so the backing remains until realm teardown. The native stack guard bounds executable nesting, but the retained domain is neither freeable at interpreter teardown nor represented in the memory inventory.
These are deterministic allocator-capacity observations, not timing or RSS claims.
Required change
- Keep ordinary shallow joins allocation-free or inline-first.
- Give fallback active-receiver storage an explicitly freeable interpreter-local owner.
- Release one-off deep high-water backing while preserving useful repeated-depth reuse.
- Publish exact current/peak receiver count, capacity, bytes, growths, releases, and released bytes through the machine-readable Context inventory without double-counting Context backing.
- Preserve entry-order identity checks and the check-before-separator-coercion behavior established by #941.
Acceptance
- Deterministic shallow/deep/locale/cycle/throw witnesses prove inline use, fallback growth, one-off release, repeated-depth reuse, shallow invalidation, and teardown zero.
- Self-cycles, mutual cycles, aliases, reentrant
toString, throwing coercions, Proxies, separators, andtoLocaleStringkeep exact observable order. - Exhaustive allocation-failure rollback leaves no active receiver, stale lease, or leaked fallback.
- Moving-GC, no-GIL, and unsuppressed TSan witnesses pass against the collecting zig-gc checkout.
- Affected test262 Array join/toLocaleString subtrees remain clean and forced tree/required-VM outcomes agree exactly.
- Versioned inventory/tool validators and teardown reconciliation pass.
- Deterministic capacity evidence is published; no noisy wall-time claim is used.
Guardrails
No reduced nesting, disabled cycle handling, global visited set, receiver/source recognition, arena-only fallback, changed separator coercion order, or cached final strings.