Goal
Let GC-backed heap-cap allocation-failure recovery attempt an abort-safe no-GIL collection only from a thread/interpreter state that can publish roots correctly, instead of failing closed whenever another shared-realm Thread is alive.
Why this is separate
Context.collectForAllocationFailure() currently has only the Context, while the abort-safe parallel collector needs the current Interpreter as the elected collector and assumes safepoint-like conditions for tracing the collector's own roots. Allocation failure can also happen from arbitrary allocation sites, including future side-store sites that may hold property/element locks. A blind allocator-level retry would be deadlock-prone and could violate the parallel collector's root-publication assumptions.
Current evidence
zig-gccallsBinding.recoverAllocationFailure()fromHeap.create()after a GC cell slab allocation fails, before the new cell is linked into the heap.Context.collectForAllocationFailure()currently returnsfalseinparallel_jswhen any JS thread is still running.Context.driveParallelCollection()already has the abort-without-sweep protocol #30 wants to reuse, but it requires the currentInterpreterand a safe publication point.
Sketch
- Add an internal current-interpreter/safepoint-owned recovery seam for active JS execution, covering host
evaluate*and spawnedThreadinterpreters. - Allow allocation-failure recovery to try the existing parallel root-publication collector only when the current thread can safely act as the collector and holds no engine side-store locks that the tracer may need.
- Return ordinary OOM unchanged when the collector cannot be safely elected or cannot converge.
- Keep side-store allocation recovery out of this slice unless it can prove the same lock-order constraints.
Acceptance criteria
- A no-GIL heap-cap witness proves a live sibling
Threaddoes not automatically force cell-allocation recovery to fail closed when a safe current interpreter can collect. - Abort/no-sweep behavior is preserved when peers do not publish or allocation continues during finish.
- No generic side-store allocator retry is introduced without a lock-order proof.
- Focused TSan coverage exercises the recovery path without parked-stack conservative scanning races.