Skip to content

Runtime: make no-GIL heap-cap recovery safepoint-owned #31

Description

@chrisbbreuer

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 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.
  • 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 current Interpreter and a safe publication point.

Sketch

  • 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions