ReviewOS

zig-utils/zig-js

GC: run post-sweep maintenance after concurrent collection

#656
Closed chris opened this 9 days ago ·
9 days ago

Parents: #476, #480 Related: #655

Problem

A single-mutator concurrent mark can finish at an evaluation-exit defer through finishConcurrentGCIfActive(). That path completes the full sweep and updates heap collection counters, but it does not run the post-sweep Context maintenance performed by synchronous collection: WebAssembly garbage reclamation, empty GC-cell suffix trimming, or automatic compaction scheduling.

At the next quiescent boundary, collectQuiescentGarbage() notices only whether finishing a marker during that call changed full_collections. If the previous evaluation-exit defer already finished the cycle and current old/young thresholds are clear, the function returns before maintenance. Empty slabs from the completed sweep can therefore remain retained until an unrelated later collection.

Scope

  • Make concurrent-cycle completion report exact finished, aborted, or inactive identity rather than inferring solely from counters.
  • Run post-full-sweep maintenance exactly once at the first safe quiescent boundary, including Wasm reclamation and ordinary or hard-cap-aware cell-tail trimming.
  • Preserve the active-interpreter/moving-compaction safety boundary; schedule compaction for a later valid moving stop rather than relocating through raw live values.
  • Cover evaluation-exit completion, explicit/quiescent collection joining, parallel abort, allocation-failure recovery, and teardown without duplicate maintenance.
  • Add a deterministic retained-slab witness that proves a completed concurrent sweep gives back eligible empty suffixes without reclaiming the live prefix.

No-workaround rules

  • No disabling concurrent GC, forcing a redundant second full collection, lowering thresholds to manufacture maintenance, deleting live slabs, or moving through unregistered raw roots.
  • No timer/retry heuristic or counter-only guess that can double-run finalizers.

Acceptance

  • Concurrent finish publishes exact completion state and post-sweep work runs once.
  • Eligible empty cell backing and Wasm garbage are reclaimed at the next safe boundary without another full sweep.
  • Live graphs, finalizers, compaction requests, OOM recovery, and teardown remain exact.
  • Focused normal/TSan, full units, concurrent/thread fuzz, and relevant nonzero conformance accounting pass with zero regressions.
9 days ago

Landed cd217904 (fix(gc): finalize concurrent sweep maintenance (#656)).

The concurrent finish path now publishes exact inactive, finished, aborted, or deferred identity; a completed sweep leaves one owner-thread pending bit that the first quiescent boundary drains into Wasm reclamation, hard-cap-aware slab trimming, and automatic-compaction policy. Explicit collection and allocation recovery accept that completed sweep instead of forcing a redundant second full collection. Marker finish also holds the GC conductor, so embedder callbacks observe an in-flight collection and reentrant GC declines safely.

Local Zig 0.17.0-dev.1818 evidence:

  • focused normal: 4 passed, 0 failed, 0 leaked;
  • focused TSan: 4 passed, 0 failed, 0 leaked, no sanitizer report;
  • real marker-thread driver: normal 4.644 s, TSan 33.495 s;
  • once-only retained-slab witness: normal 1.313 s, TSan 8.838 s;
  • full units: 1,748 passed, 1 skipped, 0 failed, 0 leaked across 10 shards;
  • conformance: 33/33 before and 33/33 after, 0 flips.

The local test262 checkout lacks its test corpus, so no test262 denominator is claimed. Keeping open for fresh Linux normal/TSan and concurrent/thread-fuzz confirmation.

9 days ago

Fresh Linux evidence for cd21790:

The normal mid-GC and lifecycle fuzz legs are still running, so I am not checking the final acceptance row or closing this issue yet.

9 days ago

Completed in cd217904.

Final evidence:

Concurrent completion now publishes exact identity and hands Context-owned Wasm/slab/compaction maintenance to the first safe boundary exactly once, without a redundant full collection.

Sign in to comment on this issue.