Pre-compile compiler functions at startup for faster JIT

The SX compiler's own functions (compile, compile-expr, compile-lambda,
etc.) are now JIT-compiled during vm-compile-adapter before any page
renders. This means all subsequent JIT compilations run the compiler
on the VM instead of CEK — aser compilation drops from 1.0s to 0.2s.

15 compiler functions pre-compiled in ~15s at startup. The compile-lambda
function is the largest (6.4s to compile). First page render aser=0.2s
(was 1.0s). Cached pages unchanged at 0.25-0.3s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 08:28:24 +00:00
parent 318c818728
commit a716e3f745

View File

@@ -865,10 +865,37 @@ let rec dispatch env cmd =
| exn -> send_error (Printexc.to_string exn))
| List [Symbol "vm-compile-adapter"] ->
(* Legacy command — JIT hook is now registered at startup.
Kept for backward compatibility with ocaml_bridge.py. *)
(* Register JIT hook and pre-compile the compiler itself.
The compile function running on the VM makes all subsequent
JIT compilations near-instant (VM speed vs CEK speed). *)
register_jit_hook env;
Printf.eprintf "[jit] JIT hook registered (lazy compilation active)\n%!";
(* Pre-compile the compiler: compile → make-emitter → make-pool
and other compiler internals so they run on VM from the start *)
let compiler_fns = ["compile"; "compile-module"; "compile-expr";
"compile-symbol"; "compile-dict"; "compile-list"; "compile-if";
"compile-when"; "compile-and"; "compile-or"; "compile-begin";
"compile-let"; "compile-lambda"; "compile-define"; "compile-set";
"compile-quote"; "compile-cond"; "compile-case"; "compile-case-clauses";
"compile-thread"; "compile-thread-step"; "compile-defcomp";
"compile-defmacro"; "compile-quasiquote"; "compile-call";
"make-emitter"; "make-pool"; "emit-byte"; "emit-u16"; "emit-i16";
"pool-add"; "resolve-scope"; "scope-resolve"] in
let t0 = Unix.gettimeofday () in
let count = ref 0 in
List.iter (fun name ->
match Hashtbl.find_opt env.bindings name with
| Some (Lambda l) when l.l_compiled = None ->
l.l_compiled <- Some Sx_vm.jit_failed_sentinel;
(match Sx_vm.jit_compile_lambda l env.bindings with
| Some cl ->
l.l_compiled <- Some cl;
incr count
| None -> ())
| _ -> ()
) compiler_fns;
let dt = Unix.gettimeofday () -. t0 in
Printf.eprintf "[jit] Pre-compiled %d compiler functions in %.3fs\n%!" !count dt;
send_ok ()
| List [Symbol "aser-slot"; String src] ->