quickjs-jit 0.12.4

JIT-enabled high level bindings to the QuickJS JavaScript engine
Documentation
# JIT M0 progress report

M0 establishes that the core numeric JIT path is profitable, preserves
QuickJS semantics, and integrates into a real GPUI workload without a material
host-heavy regression. It does not claim that Tier 1 or arbitrary JavaScript
coverage is complete.

## Performance

Lower latency is better. The focused results below are medians from 30
interleaved fresh processes after five discarded warmup processes. Every
engine produced the same checksum.

| Scenario | QuickJS | QuickJS + forced Tier 2 | Bun 1.4.0 | QuickJS vs JIT | JIT vs Bun |
| --- | ---: | ---: | ---: | ---: | ---: |
| Scalar loop | 836.946 us | 25.837 us | 12.983 us | JIT 32.39x faster | JIT 1.99x slower |
| Numeric loop | 823.818 us | 25.715 us | 12.358 us | JIT 32.04x faster | JIT 2.08x slower |
| Iterative Fibonacci, `fib(40) x 2000` | 33.780 ms | 753.907 us | 1.093 ms | JIT 44.81x faster | JIT 1.45x faster |

The numeric and Fibonacci results demonstrate a profitable native machine-code
path. Fibonacci currently exceeds Bun in this focused workload. Scalar and
numeric loops remain about 2x behind Bun, leaving room to reduce entry, guard,
boxing, and loop overhead.

These are focused forced-Tier-2 measurements, not performance guarantees for
arbitrary JavaScript. Full methodology, provenance, lifecycle metrics,
fallback counts, and machine-readable evidence are under `benchmarks/`.

### Broad JavaScript workload matrix

The broader matrix uses the same publication policy: five discarded warmup
processes, 30 interleaved fresh processes, ten independent one-second
throughput windows, and identical checksums across QuickJS interpreter, forced
Tier 1, forced Tier 2, automatic tiering, and Bun 1.4.0. The table reports the
best requested native tier only when it actually entered native code. `N/A`
means the complete worker remained interpreter-only; its timing is not
misrepresented as JIT performance.

| Workload | QuickJS | Best native JIT | Bun 1.4.0 | Result |
| --- | ---: | ---: | ---: | --- |
| Float64-dense | 2.829 ms | 322.982 us (Tier 2) | 462.551 us | JIT 8.76x faster than QuickJS and 1.43x faster than Bun |
| Strings / RegExp | 19.379 ms | N/A | 2.436 ms | No native entry; Bun 7.96x faster than QuickJS |
| Arrays / TypedArrays | 4.677 ms | 13.141 ms (Tier 1) | 770.318 us | JIT 2.81x slower than QuickJS; Bun 17.06x faster than JIT |
| Objects / polymorphic shapes | 6.687 ms | N/A | 829.039 us | No native entry; Bun 8.07x faster than QuickJS |
| Calls / recursion / closures | 7.389 ms | N/A | 1.595 ms | No native entry; Bun 4.63x faster than QuickJS |
| JSON codec | 79.053 ms | N/A | 8.844 ms | No native entry; Bun 8.94x faster than QuickJS |
| Map / Set / BigInt | 15.308 ms | N/A | 2.171 ms | No native entry; Bun 7.05x faster than QuickJS |
| Exceptions / Promise / async | 2.483 ms | N/A | 741.949 us | No native entry; Bun 3.35x faster than QuickJS |

Float64 is the only newly measured broad worker with a profitable Tier 2 path
and it exceeds Bun for this specific kernel. The array worker reaches native
Tier 1 but remains substantially unprofitable. The other six workers provide
honest QuickJS/Bun reference points while identifying native-coverage work
rather than making fallback-based speedup claims. Raw samples, tier counters,
checksums, phase timings, executable identity, and provenance are retained in
`benchmarks/results/broad-5mode.json`; the generated report is
`benchmarks/results/broad-5mode.md`.

## GPUI integration

The real `gpui-shell` paired acceptance run passes every strict gate:

- numeric layout speedup 95% CI: **39.82x..40.19x**;
- 16,835 native entries and zero fallback in the compute surface;
- host-heavy panel steady-state ratio: **0.99x..1.00x**;
- panel P99 regression CI: **-7.21%..+2.74%**;
- first-window regression CI: **-0.77%..+0.44%**;
- reload regression CI: **-3.37%..+0.84%**;
- identical checksums, snapshots, and render counts in all 30 pairs.

This shows a large gain in a suitable compute-heavy render path without a
measured regression beyond 5% in the host-heavy panel, startup, or reload
surfaces. Reproduction instructions and the tracked report are in
`integrations/gpui-component/README.md` and
`benchmarks/results/gpui-shell-jit-v1.{json,md}`.

## Implementation progress

The following core architecture is implemented:

- an independent optional `rquickjs-jit` crate;
- bounded background compilation and installation;
- a Tier 1 baseline compiler and narrow speculative Tier 2 optimizer;
- Int32/Float64 representation-aware SSA and loop Phi values;
- unboxed loop-carried numeric values;
- native Int32 add, subtract, multiply, and divide;
- exact deoptimization for overflow, type mismatch, negative zero, division
  edges, and other guarded cases;
- Float64 NaN and infinity semantics;
- compiled-to-compiled numeric calls;
- argument, return, binary, branch, call-target, and shape feedback;
- bounded specialization, versioning, retry, and demotion policies;
- OSR, adaptive hotness, profitability decisions, and backoff;
- generation-aware invalidation, hot reload, and artifact retirement;
- W^X executable memory and native unwind metadata;
- an append-only, fingerprinted QuickJS JIT ABI;
- fail-closed interpreter fallback for unsupported bytecode.

Tier 1 currently covers:

- locals, operand-stack operations, and wide control flow;
- fixed/generic calls and method calls;
- monomorphic and bounded-polymorphic property access;
- packed Array, Int32Array, and Float64Array element fast paths;
- global lookup;
- Map and Set constructor calls;
- RegExp literal construction;
- O(1) suspend and resume.

## Correctness

The full pinned applicable Test262 corpus has been evaluated in interpreter
and automatic-JIT modes:

| Mode | Files | Variants | Passed | Accountable skips | Failed |
| --- | ---: | ---: | ---: | ---: | ---: |
| Interpreter | 53,169 | 102,117 | 80,371 | 21,746 | 0 |
| Automatic JIT | 53,169 | 102,117 | 80,371 | 21,746 | 0 |

The sorted `(path, variant, status, skip_reason)` tuples are identical between
the two modes. The full evidence and pinned revision are recorded in
`docs/test262-conformance.md`.

Additional differential and integration coverage includes:

- arithmetic edge cases and observable coercions;
- exceptions and GC-visible ownership;
- property access and shape mutation;
- arrays and typed arrays;
- calls, constructors, globals, and RegExp;
- OSR, deoptimization, reload, and runtime teardown;
- randomized structured execution against the interpreter;
- GPUI snapshot and render parity;
- interpreter-only Wasm builds without Cranelift.

## Known limitations and post-M0 work

Tier 1 is not complete. Unsupported surfaces continue to fall back rather than
claiming native coverage or speedup.

1. Strings and JSON

   Add `push_atom_value` and the remaining string/property construction
   operations. Broad string and JSON workers may currently remain zero-native.

2. Arrays and typed arrays

   The element paths are exact and native transitions are bounded, but the
   guarded Tier 1 traversal is not yet a demonstrated speedup. Add valid guard
   hoisting and Tier 2 element-loop SSA.

3. Closures and recursion

   Add `fclosure` and the var-ref family while preserving captured-variable
   lifetime, reference counts, GC roots, and reload-generation isolation.

4. Map, Set, and BigInt

   Extend iterator and mutation coverage, `push_i16`, `push_bigint_i32`, and
   BigInt arithmetic. BigInt should remain helper-backed unless a native
   representation is proven safe and profitable.

5. Exceptions, Promise, and async

   Design an interpreter-compatible continuation ABI covering protected
   regions, pending exceptions, suspension, resume PCs, ownership, and Promise
   job ordering before admitting these regions to native execution.

6. General performance

   Reduce native-entry, guard, boxing, compilation, and installation overhead;
   close the remaining focused scalar/numeric gap to Bun; then rerun the full
   matrix for Float64, strings/RegExp, arrays/growth/typed arrays, object
   shapes, calls/recursion/closures, JSON, Map/Set/BigInt, and
   exceptions/Promise/async.

V8 and JavaScriptCore/Bun may be used as implementation references, but every
adopted technique still requires a QuickJS-specific proof for ownership,
exceptions, GC, invalidation, and deoptimization.

## M0 merge gate

M0 is suitable for merge when the PR's required CI checks are green. A queued,
running, cancelled, or superseded workflow is not evidence of a green merge
gate. Post-M0 limitations above are intentionally documented follow-up work
and must remain visible in future benchmark reports.