ReviewOS

zig-utils/zig-js

GC: implement moving and compacting collection

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

Parent: #134 Related: #1 and #97

Relocating collection now has precise pointer repair across every declared runtime root and edge, including concurrent/native/JIT boundaries and shared WebAssembly memory growth.

Acceptance

  • Define stable handles and relocation metadata for movable cells.
  • Rewrite stack, interpreter frame, JIT stack-map, C API, worker, promise, weak, finalization, shape, string, and host roots.
  • Preserve object identity and weak/finalization semantics across compaction.
  • Integrate write/read barriers required by concurrent access and native code.
  • Add fragmentation benchmarks, relocation stress, fault injection, leak checks, and TSan coverage.
  • Prove raw movable pointers cannot escape an untracked lifetime for the declared inventory.

Completed child map

  • #333 — pointer inventory, forwarding metadata, and rewrite contract.
  • #334 — failure-atomic stop-the-world compaction core.
  • #335 — runtime root/edge/weak/finalization rewriting.
  • #336 — concurrent mutator, native embedding, and JIT barriers.
  • #337 — fragmentation, stress, sanitizer, compatibility, and publication evidence.
  • #413 — stable zig-gc IDs with 128-byte Object allocation.
  • #414/#415/#416 — precise sibling/replacement-realm ownership and private global lifecycle.
  • #418 — current-Zig mid-GC teardown stall.
  • #425 — shared-write-safe relocating Wasm memory growth.

Exact main e3fdc52385204c75fe6ae5c64d48dae6e5ede418 passed all 43 Actions jobs.

9 days ago

Created #325 for heap-managed, precisely traced/finalized StringCells. It explicitly distinguishes static/interned/arena cells, covers every Value root/edge and external-owner reentry, and is a prerequisite for eventually relocating string roots safely rather than leaving them arena-permanent.

9 days ago

Related non-moving heap improvement landed in 6d2af84 under #325: runtime StringCells are now a traced/finalized cell kind with explicit static/arena/intern exclusions. This does not claim moving/compacting GC; it removes a permanent-allocation class needed before that work. Full matrix: https://github.com/zig-utils/zig-js/actions/runs/29700993746

9 days ago

Moving/compacting GC is now decomposed into ordered implementation gates #333–#337. The split makes the unsafe boundary explicit: first inventory and verify every movable/raw pointer (#333), then land failure-atomic stop-the-world movement (#334), complete runtime/weak/finalization rewriting (#335), add no-GIL/native/JIT barriers (#336), and only then publish terminal fragmentation/sanitizer/compatibility evidence (#337). I am treating #333 as the next actionable GC slice; no movement will be enabled by relying on untracked pinning.

9 days ago

Production-readiness evidence advanced via #353: commits 9f296900 and 06e27470 add and publish the clean fragmentation benchmark. Seven alternating samples show 90.8% lower retained backing/chunks, unchanged live slots and checksum, deterministic movement plus immediate dense fixed point, 0.99 ms median pause, and 1.00x post-action probe throughput. Raw TSV and exact revisions are committed.

9 days ago

Quiescent moving-GC coverage advanced in cc0837d via #358: a ready pointer-free baseline-JIT tier now survives relocation of its owning Function/Object graph and is entered again afterward. This removes the blanket JIT-enabled-realm rejection without claiming mid-script/native-frame movement. Debug, ReleaseSafe, TSan, C/Objective-C hosts, and relocation inventory are green.

9 days ago

Moving GC advanced in ca92af0 / #359 from quiescent-only JIT support to one declared live native safepoint. The compiler/runtime handshake distinguishes marking precision from safe post-move resumption, relocates the active registered graph, and resumes the same baseline entry. All other live/native/concurrent boundaries remain explicitly rejected pending #336.

9 days ago

C/Objective-C moving-GC integration advanced in 7b82cf9 / #360: embedders can schedule movement inside a native callback without moving that frame, then let the precise baseline checkpoint or a later quiescent direct call consume it. Counted protected-handle relocation and all host/audit modes are covered.

9 days ago

#361 landed in 373181a and closes #336. Moving collection now has failure-atomic planning/commit, complete inventoried edge/root rewrites, useful deterministic evacuation, stable Zig/C handles, exact C metrics, scheduled native-callback movement, one precise baseline-JIT movement checkpoint, and deterministic no-GIL peer deferral with suppression-free TSan evidence. The remaining closure gate is terminal evidence in #337.

9 days ago

Moving/compacting collection is complete across the compiler-enforced relocation inventory, failure-atomic movement, all runtime roots/edges, weak/finalization/native/Wasm boundaries, quiescent and scheduled C/JIT entry points, and no-GIL deferral. The committed benchmark reports 90.8% less retained backing with a 0.99 ms median pause and no post-action throughput loss. Descendant full CI is green: https://github.com/zig-utils/zig-js/actions/runs/29716788619.

9 days ago

All declared relocation children are complete, including the final concurrent Wasm growth boundary (#425), and exact main passed 43/43 jobs.

Sign in to comment on this issue.