Goal
Make zig-js broadly faster than JavaScriptCore on representative JavaScript and WebAssembly workloads—not merely the current ten-kernel matrix—while preserving exact ECMAScript/WebAssembly semantics, precise/moving-GC safety, GIL-free correctness, bounded resources, and reproducible evidence.
This is the successor performance roadmap to completed #44. It does not reopen or diminish #44: the July 29 matrix already records 10/10 zig-js wins in all directly comparable modes. It expands the target to the performance surfaces that the current matrix does not cover and to the measured gaps that remain.
Current evidence boundary
Already green
The accepted clean-tree publication at 018517d2 measures runtime 14d94ec0:
- direct warmed context: 10/10 wins, 2.32x geometric-mean throughput;
- eight independent steady contexts: 10/10 wins, 2.53x throughput, 5.35x scaling;
- eight independent cold lifecycles: 10/10 wins, 2.52x throughput, 5.67x scaling;
- shared realm: 4.84x geometric-mean scaling at eight lanes, with no public-JSC-equivalent ratio.
Evidence: report and 1,540 raw samples.
Measured gaps
- Wasm SIMD is only 0.10–0.14x JSC throughput at eight independent contexts because fixed-width SIMD currently executes through the portable interpreter rather than native vector instructions: report.
- Shared object churn reaches only 1.48x eight-lane scaling in the latest accepted matrix, far below the near-linear compute rows.
- Moving age-three GC is 0.63x its non-moving parent on high-survival work and 0.80x on shared mixed-survival work; shared moving pauses reach 110.56 ms with bounded rendezvous retries: report.
- A no-GIL shape-mutation witness records 271,244 optimizer publications and 271,244 invalidations versus 40 publications and zero invalidations serialized, because Class-A invalidation is owner-wide.
- Native optimizer publication is declared only on macOS AArch64. macOS x86-64 and Linux remain baseline/bytecode fallbacks.
- The VM flat-slot model cannot represent block shadowing, TDZ, or per-iteration captured bindings, so substantial correct JavaScript never reaches bytecode or native tiers.
- The comparison matrix does not cover strings, RegExp, JSON, Maps/Sets, typed arrays, promises/async, modules, classes, iterators, Intl, Temporal, proxy/accessor-heavy objects, large application graphs, warmup cost, code size, or memory efficiency.
Non-negotiable engineering contract
- Owned dependency boundary. Production engine/package dependencies may only be zig-utils-owned sibling checkouts under
~/Code/**(currently../zig-regexand../zig-gc). Do not add a network package, vendored third-party runtime, system JS engine, C/C++ engine, or opaque binary dependency. External standards corpora and system JSC remain pinned, test/benchmark-only oracles, never library dependencies. - No workarounds. No source/function/benchmark recognition; no checksum shortcuts; no disabled safety/GC/barrier/checkpoint behavior; no benchmark-only tier selection; no silent fallback described as completion; no permanent suppressions; no threshold-only change presented as a root-cause fix; no unbounded cache/pool/reserve used to buy a score.
- Semantics first. Every optimization preserves exceptions, evaluation order, observable effects, OOM atomicity, step/watchdog accounting, debugger/termination behavior, precise roots, moving relocation, invalidation, and no-GIL synchronization.
- Causal evidence. Retained optimizations need exact-parent A/B evidence, profile attribution, identical work/checksums, memory/RSS accounting, and focused semantic/TSan gates. Rejected candidates stay documented and reverted.
- No universal claims from microbenchmarks. Workload-scoped evidence remains explicit. Broader claims require broader representative matrices.
- Portable correctness. Unsupported native backends must fail closed to exact lower tiers until they have the same differential, GC, sanitizer, and performance evidence as macOS AArch64.
Roadmap structure
Child issues are grouped into:
- performance evidence and anti-regression infrastructure;
- dependency sovereignty and owned tooling;
- bytecode, baseline JIT, optimizer, object model, and built-in hot paths;
- GC, allocation, shared-realm scaling, startup, and memory;
- WebAssembly native execution and SIMD/threads;
- backend portability and cross-tier differential verification.
Child issue map
Evidence and owned dependencies
- #460 — representative dependency-free benchmark matrix
- #461 — causal attribution and exact-parent regression infrastructure
- #503 — cycles, cache behavior, energy, and thermal stability
- #504 — independent suites and additional engines, out of tree
- #462 — owned local dependency and offline-build enforcement
JavaScript frontend and execution tiers
- #465 — universal semantically correct bytecode eligibility
- #498 — fast no-JIT execution tier for restricted hosts
- #499 — versioned bytecode, immutable realm snapshots, and AOT artifacts
- #466 — general resumable baseline regions and precise stack maps
- #467 — optimizer environments, closures, classes, iterators, and general control
- #468 — call inlining, escape analysis, and scalar replacement
- #469 — global value/loop/range/effect-aware optimization
- #470 — unboxed representation selection
- #471 — precise artifact invalidation and broader property ICs
- #472 — native arrays, typed arrays, DataView, and indexed loops
- #473 — owned string, RegExp, and JSON performance
- #474 — promises, async/generators, microtasks, and module graphs
- #475 — collections, Date, Intl, and Temporal
- #496 — lexing, parsing, bytecode, and module compilation
GC, memory, startup, and concurrency
- #476 — parallel/short shared precise collection pauses
- #477 — survival-aware, copy-efficient moving generations
- #478 — shared allocation/object-model scaling
- #479 — cold context startup and teardown
- #480 — bounded heap/cache/executable footprint
- #481 — tiering, warmup, compilation cost, and code value
- #482 — Thread/Worker/channel/join lifecycle
- #502 — coordinated GC/JIT/Wasm/worker CPU and memory budgets
Native backends
- #483 — backend-neutral codegen and W^X contract
- #501 — generated-code symbols, unwind metadata, and exact native stacks
WebAssembly
- #486 — native-Wasm performance roadmap
Cross-cutting release gates
- #491 — differential fuzzing across every tier/backend
- #492 — long-running latency, memory plateau, and cleanup
- #493 — adversarial complexity and worst-case latency
- #494 — compile/link/test feedback time
- #495 — Zig/C/private/Objective-C embedding boundaries
Recommended execution order
- Measure and enforce first: #460, #461, #462, #503, and #504. These freeze the broader scorecard, causal/efficiency evidence format, dependency rules, and independent validation before implementation can optimize the wrong target. Begin #497 after #462 classifies the complete tooling graph.
- Attack proven largest gaps: #483 → #487 → #488 for the 7–10x Wasm SIMD deficit; #476 → #477/#478 for moving/shared allocation costs; #471 for the measured no-GIL invalidation storm.
- Broaden tier eligibility and optimization: #465 → #498 → #466 → #467, followed by #468–#472 and #481. Build #499 on the stable bytecode/no-JIT contracts. Backend work #483 → #484/#485/#500 proceeds in parallel once the shared contract is stable, with #501 required for publishable native attribution.
- Cover application hot paths: #473–#475, #479, #482, #495, and #496, each driven by frozen #460 rows rather than microbenchmark guesses.
- Prove sustained production behavior: #480, #491–#494, #502/#503, the full owned and independent matrices, cross-backend/restricted-host evidence, and only then the program-level completion claim.
An issue may start early for investigation/instrumentation, but it must not publish a performance completion result before its declared predecessors provide the required contract/evidence.
Program-level completion gate
- Every child is complete with its own causal evidence and correctness gates.
- The expanded representative matrix is fully defined before “win all benchmarks” is evaluated.
- zig-js wins every directly comparable accepted row on the declared reference platforms, with no noise-qualified regression in the original #44 matrix.
- Wasm SIMD reaches or exceeds JSC on every accepted integer, float, shuffle, and memory row.
- Shared-realm allocation-heavy rows scale monotonically and meet their child issue floors without unbounded retained memory.
- GC pause/throughput objectives are met on ephemeral, mixed, high-survival, and shared workloads.
- Every declared native backend passes forced-on/off differential, moving-GC, no-GIL, TSan, termination, debugger, and artifact-lifetime gates.
- Every declared no-JIT/restricted platform passes its fast-VM/AOT contract without attempting forbidden executable mappings.
- Independent-suite evidence corroborates repository-owned results without adding a build/runtime dependency.
- Throughput wins retain bounded cycles, cache traffic, energy, thermal behavior, memory, and code size on hosts that expose trustworthy measurements.
- Production and documentation dependency audits enforce the owned-local policy.
- README/docs claims are regenerated only from clean, committed raw evidence.
Related completed foundations
#44, #49, #52, #97, #132, #133, #144, #145, #146, #283, #426, #431, #432, #433, #434, #437, #438, #439, #440, #445, #446, #447, #448, #450, #451, #452.