Skip to content

perf(jit): specialize mixed calls and native property guards - #26

Draft
huacnlee wants to merge 1 commit into
mainfrom
perf/bun-guided-native-overhead
Draft

perf(jit): specialize mixed calls and native property guards#26
huacnlee wants to merge 1 commit into
mainfrom
perf/bun-guided-native-overhead

Conversation

@huacnlee

@huacnlee huacnlee commented Sep 9, 2026

Copy link
Copy Markdown
Member

Short mixed-argument calls and monomorphic property access repeatedly cross runtime boundaries. Add a narrow Int32/Bool compiled-to-compiled ABI for pure forward-branch leaves, and emit native property guards using an ABI-described, non-reused shape generation token. Rooted property hits avoid the C guard and eager frame publication; guard misses reconstruct the original bytecode state. Also admit mixed numeric array loops to existing guarded automatic Tier 2 trials, reduce cold metric publication, and cache safe resident artifact lookups.

Paired fixed-warmup results against the PR #25 runtime show 26.20x generic-call-entry, 6.91x property-heavy, and 2.65x arrays-typed speed, respectively 3.99x, 3.17x, and 1.64x their same-version QuickJS interpreter. The call gain combines enabling the compiled caller and direct leaf ABI; it is not an isolated generic-call cost comparison. A new effectful generic-call-fallback keeps the non-direct/native-entry workload visible: it improves 1.205x over the old JIT but remains only 0.339x QuickJS speed. These three priority workloads still trail default Bun substantially.

The README reports every one of the 24 QuickJS/Bun/automatic-JIT scenarios, including slower, tied, and fallback results. The shared driver applies equal warmup, consumes every result, and checks checksums outside timing. Raw samples, immutable source snapshots, binary hashes, paired confidence intervals, and host measurements are archived. This measures fixed-warmup batch latency, not peak Bun or matched settled-state throughput.

ABI minor advances to 21 with a checked PropertyLayout descriptor. On the measured x86_64 build, JSShape grows from 64 to 72 bytes and JSRuntime grows by 8 bytes; JSFunctionBytecode stays at 160 bytes. The earlier PC-cache experiment was removed after host regression isolation. Numeric coercion, overflow, target replacement, shape/descriptor mutation, ownership, and exact deoptimization paths retain guarded recovery. Full LICM, bounds-check elimination, general inlining, and closure/async ABI expansion are outside this change.

Validation: Exact final source passed 52 release semantic/differential/GPUI-surface tests and 340 C/Rust AddressSanitizer tests (generated JIT machine code itself is not ASAN-instrumented). The pinned historical GPUI Shell harness passed 10 tests with 1 ignored. A compiler-only production_api trybuild diagnostic mismatch reproduces on baseline and candidate; this check is not reported as passing. Scalar and call-heavy paired controls are statistically tied with the old JIT; their confidence bounds satisfy this run's 0.95x speed budget. This does not establish every M2 gate.

Draft: host regression remains unresolved. Final mixed-host steady snapshots are 1.154x [1.146, 1.161] the old JIT speed, but compute hot reload is only 0.944x [0.937, 0.952] and fails the 0.95x budget. Its interpreter control is 0.933x [0.930, 0.935] in steady snapshots. Compute automatic steady state is statistically tied (between 11.1% slower and 19.8% faster). The final regression is not causally attributed to the removed PC cache; investigation is still needed before merge. All final raw observations are retained without additional confirmation rounds.

Refs #14. Follows #25.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant