You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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-gc calls Binding.recoverAllocationFailure() from Heap.create() after a GC cell slab allocation fails, before the new cell is linked into the heap.
Context.collectForAllocationFailure() currently returns false in parallel_js when any JS thread is still running.
Add an internal current-interpreter/safepoint-owned recovery seam for active JS execution, covering host evaluate* and spawned Thread interpreters.
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 Thread does 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.
Parent: #30 / #1
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
Threadis alive.Why this is separate
Context.collectForAllocationFailure()currently has only theContext, while the abort-safe parallel collector needs the currentInterpreteras 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 Runtime: extend heap-cap emergency recovery beyond current safe allocation classes #30 wants to reuse, but it requires the currentInterpreterand a safe publication point.Sketch
evaluate*and spawnedThreadinterpreters.Acceptance criteria
Threaddoes not automatically force cell-allocation recovery to fail closed when a safe current interpreter can collect.