cranelift: route OP_WINDOW / OP_WINDOW_VIEW through extern helpers#386
Merged
Conversation
Both arms previously bailed JIT compilation (`return None`) because the VM dispatcher's OP_WINDOW emits `HeapObj::ListView` strides and the inlined LISTGET / FOREACHPREP / FOREACHNEXT fast paths read Vec metadata at fixed offsets that would UB on a view's struct layout. Any function touching window opcodes fell back to the VM dispatcher. Fix: emit calls to the existing `jit_window` / `jit_window_view` extern helpers. Both helpers always return owning `HeapObj::List`s (no views), so subsequent inlined foreach reads operate on the expected Vec layout and remain sound. The function compiles, the rest of the hot path runs JIT-native (notably bio-canonical-shape `flt p (window k xs)`), and we trade the VM dispatcher's per-stride ListView win for the much larger JIT-compiled outer loop. OP_WINDOW_VIEW is a two-word encoding; the data word at ip+1 holds the n register in its A field. `skip_next = true` consumes it, mirroring OP_SLC / OP_LST / OP_MSET / OP_RGXSUB.
Cross-engine regression test exercises every shape that previously bailed JIT compilation: plain `window`, foreach over a window result, and the fused `flt p (window n xs)` shape that triggers OP_WINDOW_VIEW. Each asserts parity across `--run-tree`, `--run-vm`, and `--run-cranelift`. Companion `examples/window-cranelift-jit.ilo` pins the same shapes for the engine harness so future agents see the now-correct behaviour.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced May 18, 2026
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.
Summary
Cranelift's JIT used to bail out (
JitCallError::NotEligible) on any function containingOP_WINDOWorOP_WINDOW_VIEW, forcing entire hot paths back to the VM dispatcher. The reason: the VM dispatcher's OP_WINDOW emitsHeapObj::ListViewstrides, and Cranelift's inlined LISTGET / FOREACHPREP / FOREACHNEXT fast paths read Vec metadata at fixed offsets that would UB on a view's struct layout.Fix: emit calls to the existing
jit_window/jit_window_viewextern helpers in both arms. Both helpers always return owningHeapObj::Lists (never views), so subsequent inlined foreach reads operate on the expected Vec layout and remain sound. We trade the VM dispatcher's per-stride ListView win for the much larger JIT-compiled outer loop, which is exactly the trade bio-canonical-shapeflt p (window k xs)needs.Repro before / after
f xs:L n>L (L n);window 3 xson--run-cranelift:What's in the diff
cranelift: route OP_WINDOW / OP_WINDOW_VIEW through extern helpers(src/vm/jit_cranelift.rs) — replaces thereturn Nonebail with calls tohelpers.window(3 args) andhelpers.window_view(5 args). OP_WINDOW_VIEW is a two-word op;skip_next = trueconsumes the data word holding the n register, mirroring OP_SLC / OP_LST / OP_MSET / OP_RGXSUB. Stale audit comments referencing the bail in OP_FOREACHPREP / OP_LISTGET remain accurate (no view reaches them under JIT because the helpers materialise to Lists).test: cover OP_WINDOW / OP_WINDOW_VIEW on cranelift JIT(tests/regression_window_cranelift.rs,examples/window-cranelift-jit.ilo) — 5 cross-engine regression tests across tree / VM / cranelift covering plainwindow, foreach-over-window, the fusedflt p (window n xs)shape (OP_WINDOW_VIEW), size-1 windows, and n>len. Example file pins the same shapes for the engine harness.Test plan
cargo test --release --features cranelift --test regression_window_cranelift— 5/5 passcargo test --release --features cranelift— full suite greencargo fmt --checkcleancargo clippy --release --features cranelift --all-targets -- -D warningscleanilo --run-cranelift 'main xs:L n>L n;ws=window 3 xs;hd ws' 1,2,3,4,5→[1, 2, 3]Follow-ups
HeapObj::ListViewvia a[ptr+0] == 1discriminant guard, fall back to thelistgethelper on mismatch, and then let OP_WINDOW emit views directly. That recovers the per-stride ListView win that the VM dispatcher currently has exclusively, on top of JIT-compiled outer loops. Out of scope here; the helper-routing path is the smaller, safer first step.