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
Follow-up from #29 after zig-gc b99de49, zig-js 78b553a, and zig-js 45a58ce promoted semantics/oom-one-thread.js and added ArrayBuffer byte-slab recovery.
Current status
The landed recovery paths cover these GC-backed capped-context allocation failures:
GC cell slab allocation failures retry after Context.collectForAllocationFailure() when the current thread can safely collect.
no-GIL GC-cell slab recovery has a safepoint-owned current-interpreter path from Runtime: make no-GIL heap-cap recovery safepoint-owned #31; it reuses the abort-safe parallel root-publication collector and retries only after a collection actually sweeps.
GC-backed ArrayBuffer byte allocation failures retry once after the same recovery hook.
Budgeted runtime allocations now have a guarded one-shot recovery hook (2d4d3ae0): when the heap cap would be exceeded, the quota allocator can collect safely, reserve again, and continue without scattering ad-hoc retries through object/property code.
GC-backed object side-store garbage can now be reclaimed by allocation-failure recovery under the heap cap (Context heap_limit_bytes object side-store pressure recovers garbage).
72beb646 blocks the generic budget-recovery callback inside GcCellBacking allocator-internal critical sections, so GC-cell chunk OOM fails outward to zig-gc's safe outer Heap.create recovery path instead of self-deadlocking while backing locks are held.
b3c86930 roots pre-reserved heap-limit catch environments in the interpreter's precise environment root stack, so emergency recovery cannot collect a catch scope needed to convert reserved OutOfMemoryError values into JS catch (e) bindings.
Single-threaded and GIL-mode contexts can run emergency collection safely when peers are parked/published under the supported scan policy.
Arena-backed heap caps remain fail-closed and non-reclaimable by design.
That is enough for the PR-249 OOM recovery witness, GC-backed ArrayBuffer byte pressure, ordinary budgeted GC-backed side-store pressure, and the current no-GIL GC-cell emergency-recovery slice, while keeping collection fail-closed when peers could hold unscanned roots or when the current allocation site holds a trace-sensitive lock.
Side-store policy covered so far
Object side-store pressure is now covered by focused tests:
dropped object side stores are reclaimable by explicit collection, and a second allocation wave can then succeed under the same GC-backed cap;
allocation-failure recovery now also reclaims dropped side stores automatically in safe single-threaded/GIL-capable contexts;
live side-store pressure still fails closed as host error.OutOfMemory, proving the cap is enforced when collection cannot free enough budget.
The recovery hook is intentionally guarded, recursion-safe, and disabled inside allocator-internal backing locks rather than a blanket retry. Many no-GIL side-store allocations can happen while object property/element or other trace-sensitive locks are held, while GC tracing may need those same locks.
Remaining perfection work
Extend abort-safe no-GIL / parallel_js emergency recovery beyond the current safepoint-owned GC-cell path, without scanning unpublishing peers or weakening the fail-closed policy.
Define finer lock-aware no-GIL collect/retry policies for side stores and other non-cell allocations where the allocation site can prove it does not hold locks the tracer needs.
Add focused tests for every newly recoverable allocation class; keep fail-closed witnesses for allocation classes that remain unsafe to recover generically.
Keep arena-backed heap caps fail-closed unless a caller explicitly opts into GC-backed recovery.
This should stay separate from #29/#24: the promoted PR-249 witness is covered, but capped allocation recovery is not yet perfect for every allocation class or no-GIL interleaving.
Follow-up from #29 after zig-gc b99de49, zig-js 78b553a, and zig-js 45a58ce promoted
semantics/oom-one-thread.jsand added ArrayBuffer byte-slab recovery.Current status
The landed recovery paths cover these GC-backed capped-context allocation failures:
Context.collectForAllocationFailure()when the current thread can safely collect.2d4d3ae0): when the heap cap would be exceeded, the quota allocator can collect safely, reserve again, and continue without scattering ad-hoc retries through object/property code.Context heap_limit_bytes object side-store pressure recovers garbage).72beb646blocks the generic budget-recovery callback insideGcCellBackingallocator-internal critical sections, so GC-cell chunk OOM fails outward to zig-gc's safe outerHeap.createrecovery path instead of self-deadlocking while backing locks are held.b3c86930roots pre-reserved heap-limit catch environments in the interpreter's precise environment root stack, so emergency recovery cannot collect a catch scope needed to convert reservedOutOfMemoryErrorvalues into JScatch (e)bindings.That is enough for the PR-249 OOM recovery witness, GC-backed ArrayBuffer byte pressure, ordinary budgeted GC-backed side-store pressure, and the current no-GIL GC-cell emergency-recovery slice, while keeping collection fail-closed when peers could hold unscanned roots or when the current allocation site holds a trace-sensitive lock.
Side-store policy covered so far
Object side-store pressure is now covered by focused tests:
error.OutOfMemory, proving the cap is enforced when collection cannot free enough budget.The recovery hook is intentionally guarded, recursion-safe, and disabled inside allocator-internal backing locks rather than a blanket retry. Many no-GIL side-store allocations can happen while object property/element or other trace-sensitive locks are held, while GC tracing may need those same locks.
Remaining perfection work
parallel_jsemergency recovery beyond the current safepoint-owned GC-cell path, without scanning unpublishing peers or weakening the fail-closed policy.This should stay separate from #29/#24: the promoted PR-249 witness is covered, but capped allocation recovery is not yet perfect for every allocation class or no-GIL interleaving.