From 13ba5ee42320df70e687e7fad3f17a83713d411d Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 24 Mar 2026 18:34:27 +0000 Subject: [PATCH] Unify JIT to lazy-only: remove allowlist, all lambdas compile on first call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the manual jit_allowlist (StringSet of ~40 function names) with universal lazy compilation. Every named lambda gets one compile attempt on first call; failures are sentineled and never retried. Compiler internals are still pre-compiled at startup (bootstrapping the JIT itself), but everything else compiles lazily — no manual curation. Remove jit-allow command (no longer needed). Remove StringSet module. Co-Authored-By: Claude Opus 4.6 (1M context) --- hosts/ocaml/bin/sx_server.ml | 80 +++++++++++++----------------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/hosts/ocaml/bin/sx_server.ml b/hosts/ocaml/bin/sx_server.ml index 47d62e2..1bdade7 100644 --- a/hosts/ocaml/bin/sx_server.ml +++ b/hosts/ocaml/bin/sx_server.ml @@ -665,32 +665,8 @@ let sx_render_to_html expr env = CEK, cache result). cek_call checks this before CEK dispatch. *) let _jit_compiling = ref false (* re-entrancy guard *) -(** Functions allowed for JIT compilation. Others go straight to CEK. - Populated with compiler internals at registration time; extended - dynamically via (jit-allow name) command. *) -module StringSet = Set.Make(String) -let jit_allowlist = ref (StringSet.of_list [ - (* Compiler internals *) - "compile"; "compile-module"; "compile-expr"; "compile-symbol"; - "compile-dict"; "compile-list"; "compile-if"; "compile-when"; - "compile-and"; "compile-or"; "compile-begin"; "compile-let"; - "compile-letrec"; "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-qq-expr"; - "compile-qq-list"; "compile-call"; - "make-emitter"; "make-pool"; "make-scope"; "pool-add"; - "scope-define-local"; "scope-resolve"; - "emit-byte"; "emit-u16"; "emit-i16"; "emit-op"; "emit-const"; - "current-offset"; "patch-i16"; - (* Parser *) - "sx-parse"; "sx-serialize"; "sx-serialize-dict"; - (* Pure transforms *) - "aser"; "resolve-nav-path"; "tw"; "serialize"; - "render-to-html"; "render-attrs"; "render-html-element"; - "merge-spread-attrs"; "cssx-process-token"; - "signal"; "computed"; "freeze-scope"; "freeze-signal"; -]) +(* JIT compilation is lazy-only: every named lambda gets one compile + attempt on first call. Failures are sentineled (never retried). *) let register_jit_hook env = Sx_ref.jit_call_hook := Some (fun f args -> @@ -710,7 +686,6 @@ let register_jit_hook env = | None -> let fn_name = match l.l_name with Some n -> n | None -> "?" in if !_jit_compiling then None - else if not (StringSet.mem fn_name !jit_allowlist) then None else begin _jit_compiling := true; let t0 = Unix.gettimeofday () in @@ -879,34 +854,37 @@ let rec dispatch env cmd = | exn -> send_error (Printexc.to_string exn)) | List [Symbol "vm-compile-adapter"] -> - (* Register JIT hook — all functions in the allowlist compile lazily - on first call. Pre-compile the compiler itself so subsequent - JIT compilations run at VM speed, not CEK speed. *) + (* Register lazy JIT hook — all named lambdas compile on first call. + Pre-compile compiler internals so subsequent JIT compilations + run at VM speed, not CEK speed. *) register_jit_hook env; let t0 = Unix.gettimeofday () in let count = ref 0 in - (* Pre-compile compiler internals only — these bootstrap the JIT. - Everything else (render, aser, parser) compiles lazily on first call. *) - StringSet.iter (fun name -> - if String.length name >= 7 && String.sub name 0 7 = "compile" - || List.mem name ["make-emitter"; "make-pool"; "make-scope"; "pool-add"; - "scope-define-local"; "scope-resolve"; - "emit-byte"; "emit-u16"; "emit-i16"; "emit-op"; "emit-const"; - "current-offset"; "patch-i16"] then - 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 -> ()) - | _ -> () - ) !jit_allowlist; + let compiler_names = [ + "compile"; "compile-module"; "compile-expr"; "compile-symbol"; + "compile-dict"; "compile-list"; "compile-if"; "compile-when"; + "compile-and"; "compile-or"; "compile-begin"; "compile-let"; + "compile-letrec"; "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-qq-expr"; + "compile-qq-list"; "compile-call"; + "make-emitter"; "make-pool"; "make-scope"; "pool-add"; + "scope-define-local"; "scope-resolve"; + "emit-byte"; "emit-u16"; "emit-i16"; "emit-op"; "emit-const"; + "current-offset"; "patch-i16"; + ] 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_names; let dt = Unix.gettimeofday () -. t0 in - Printf.eprintf "[jit] Pre-compiled %d compiler functions in %.3fs (lazy JIT active)\n%!" !count dt; - send_ok () - - | List [Symbol "jit-allow"; String name] -> - jit_allowlist := StringSet.add name !jit_allowlist; + Printf.eprintf "[jit] Pre-compiled %d compiler functions in %.3fs (lazy JIT active for all)\n%!" !count dt; send_ok () | List [Symbol "set-request-cookies"; Dict cookies] ->