perf(jit): reduce native entry, feedback, and PC validation overhead - #18
Merged
Conversation
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue # (if available)
Follow-up to M2 (#16).
Description of changes
Generic native calls repeatedly acquired and released entry handles and allocated return/argument feedback storage. Cache one idle pc=0 entry handle per QuickJS runtime, replace the native-return queue with a synchronous inline handoff, reuse CALL feedback storage after warmup, and resume helper PC validation from a previously verified instruction boundary.
entry_cache_epochquery, bump JIT ABI minor to 20, and update the vtable fingerprint, bundled bindings, and patch manifest. OSR handles remain uncached.The final cursor diagnostic records 1.356x M2 speed for generic calls in automatic mode (actually Tier 1; paired 95% interval: 35.3%–35.9% faster). Relative to the complete pre-cursor version, Tier 1 generic calls are 1.135x speed, direct calls 2.226x, and recursive Fibonacci 1.108x; automatic generic calls improve only to 1.007x. CALL-buffer reuse independently eliminates warmed allocations; its earlier incremental timing result was statistically tied.
There are small measured tradeoffs: focused 60-pair repeats retain automatic direct-call speed of 0.979x the pre-cursor baseline (1.3%–3.3% slower) and Tier 2 scalar-loop speed of 0.985x (1.1%–2.2% slower). Direct-call Tier 2 and automatic scalar-loop repeats are statistically tied. Reports preserve raw samples, exact executable/script hashes, the cursor patch, and reproduction drivers. The profiler's helper-frame share falls from 36.08% to 18.24% of self sampled cycles; that attribution is not an overall speed claim.
The pre-cursor clean-source matrix is archived with raw evidence: 22 workloads, four modes, and 2,640 retained samples. The overall performance acceptance gate still fails: Tier 2 compute speed is 3.17x–3.23x the interpreter baseline (below the 5x target), startup/reload gates fail, and host-integration evidence is absent. Checksum, required native-entry, automatic-policy, and aggregate P99 gates pass. That matrix predates the cursor change; it is not acceptance evidence for the final revision. Its mode comparisons are separate from the revision diagnostics above. Report labels now distinguish qualifying native entries for each requested tier. See
docs/M3.mdfor evidence, ownership proofs, and limitations.Validation on final code:
cargo test --release -p quickjs-jit-runtime --features compiler,test-support --tests--features full-async,bindgen -- -D warnings; formatting checkCI for the cursor commit remains pending. Its parent b7be6a4 passed 41 checks, including memory, address, and thread sanitizers. Per-call hot/enter/exit bookkeeping, feedback/tier-state lookups, and remaining frame-validation work persist; this PR does not complete the broader native-call-overhead target.
Checklist