vm-ext: phase E — JIT skips lambdas containing extension opcodes
Adds Sx_vm.bytecode_uses_extension_opcodes — an operand-aware bytecode scanner that walks past CONST u16, CALL_PRIM u16+u8, and CLOSURE u16+dynamic upvalue descriptors so operand bytes that happen to be ≥200 don't false-positive as extension opcodes. jit_compile_lambda calls the scanner on the inner closure's bytecode. On hit it returns None — the lambda then runs through CEK interpretation. The VM's dispatch fallthrough still routes the extension opcodes themselves through the registry; this change just prevents the JIT from claiming code it has no plan for. Tests: 7 new foundation cases — pure core eligible, head/middle/ post-CLOSURE detection, CONST + CALL_PRIM + CLOSURE-descriptor false- positive avoidance. +7 pass vs Phase D baseline, no regressions across 11 conformance suites. Loop complete: acceptance criteria 1-4 met. Hand-off to the Erlang loop — lib/erlang/vm/dispatcher.sx's Phase 9b stub can now be replaced with a real hosts/ocaml/lib/extensions/erlang.ml consumer.
This commit is contained in:
@@ -8,7 +8,10 @@ future language port that wants performance-critical opcodes.
|
||||
Reference: `plans/erlang-on-sx.md` Phase 9, `plans/fed-sx-design.md` §17.5,
|
||||
`hosts/ocaml/lib/sx_vm.ml` (current VM).
|
||||
|
||||
Status: **in progress** on `loops/sx-vm-extensions`.
|
||||
Status: **complete** on `loops/sx-vm-extensions` (Phases A-E landed
|
||||
2026-05-14 / 2026-05-15). Ready for first real consumer
|
||||
(`hosts/ocaml/lib/extensions/erlang.ml`, replacing the Phase 9b stub
|
||||
dispatcher in `lib/erlang/vm/dispatcher.sx`).
|
||||
|
||||
---
|
||||
|
||||
@@ -317,9 +320,9 @@ The JIT (lazy lambda compilation) currently compiles based on opcode ranges.
|
||||
Extension opcodes (≥200) should fall through to interpretation, not be
|
||||
JIT-compiled in v1.
|
||||
|
||||
- [ ] Mark extension opcodes as "interpret only" in the JIT pre-analysis.
|
||||
- [ ] Lambda containing only core opcodes JIT-compiles as before.
|
||||
- [ ] Lambda containing any extension opcode runs interpreted.
|
||||
- [x] Mark extension opcodes as "interpret only" in the JIT pre-analysis.
|
||||
- [x] Lambda containing only core opcodes JIT-compiles as before.
|
||||
- [x] Lambda containing any extension opcode runs interpreted.
|
||||
|
||||
JITing extension opcodes is a follow-up project; v1 keeps the JIT scope
|
||||
unchanged and just makes it correctly route mixed bytecode.
|
||||
@@ -457,6 +460,29 @@ familiarity.
|
||||
|
||||
Newest first.
|
||||
|
||||
- **2026-05-15** — Phase E done. Loop complete (acceptance criteria
|
||||
1-4 all met). New `Sx_vm.bytecode_uses_extension_opcodes` walks
|
||||
bytecode operand-aware (CONST u16 indices, CALL_PRIM u16+u8,
|
||||
CLOSURE u16+dynamic upvalue descriptors) so values that happen to
|
||||
be ≥200 don't false-positive as extension opcodes. Wired into
|
||||
`jit_compile_lambda`: when the inner closure's bytecode contains
|
||||
any extension opcode, JIT returns None and the lambda runs
|
||||
interpreted via CEK (the dispatch fallthrough still routes
|
||||
extension opcodes through the registry — this just prevents the
|
||||
JIT from claiming ownership of code it can't optimise). 7 new
|
||||
foundation tests (`jit extension-opcode awareness` suite): pure
|
||||
core eligible, head/middle/post-CLOSURE detection, CONST + CALL_PRIM
|
||||
+ CLOSURE-descriptor false-positive avoidance. +7 pass vs Phase D
|
||||
baseline (4833 vs 4826), 1111 pre-existing failures unchanged.
|
||||
Conformance suites green: erlang 530/530, haskell 285/285, datalog
|
||||
276/276, prolog 590/590, smalltalk 847/847, common-lisp 487/487,
|
||||
apl 562/562, js 148/148, forth 632/638 (pre-existing), tcl 3/4
|
||||
(pre-existing), ocaml-on-sx unit 607/607.
|
||||
|
||||
Loop done. Hand-off: the Erlang loop's Phase 9b stub dispatcher in
|
||||
`lib/erlang/vm/dispatcher.sx` can now be replaced with a real
|
||||
`hosts/ocaml/lib/extensions/erlang.ml` consumer.
|
||||
|
||||
- **2026-05-15** — Phase D done. New `hosts/ocaml/lib/extensions/` subtree
|
||||
wired into the `sx` library via `(include_subdirs unqualified)`.
|
||||
`extensions/test_ext.ml` is the canonical worked example: two
|
||||
|
||||
Reference in New Issue
Block a user