From a716e3f745aa946c6f002de9b6224b30df845a30 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 23 Mar 2026 08:28:24 +0000 Subject: [PATCH] Pre-compile compiler functions at startup for faster JIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- hosts/ocaml/bin/sx_server.ml | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/hosts/ocaml/bin/sx_server.ml b/hosts/ocaml/bin/sx_server.ml index ddda6d1..1710a08 100644 --- a/hosts/ocaml/bin/sx_server.ml +++ b/hosts/ocaml/bin/sx_server.ml @@ -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] ->