JIT allowlist + integration tests + --test mode + clean up debug logging
JIT allowlist (sx_server.ml): - Replace try-every-lambda strategy with StringSet allowlist. Only functions in the list get JIT compiled (compiler, parser, pure transforms). Render functions that need dynamic scope skip JIT entirely — no retry overhead, no silent fallbacks. - Add (jit-allow name) command for dynamic expansion from Python bridge. - JIT failures log once with "[jit] DISABLED fn — reason" then go silent. Standalone --test mode (sx_server.ml): - New --test flag loads full env (spec + adapters + compiler + signals), supports --eval and --load flags. Quick kernel testing without Docker. Example: dune exec bin/sx_server.exe -- --test --eval '(len HTML_TAGS)' Integration tests (integration_tests.ml): - New binary exercising the full rendering pipeline: loads spec + adapters into a server-like env, renders HTML via both native and SX adapter paths. - 26 tests: HTML tags, special forms (when/if/let), letrec with side effects, component rendering, eval-expr with HTML tag functions. - Would have caught the "Undefined symbol: div/lake/init" issues from the previous commit immediately without Docker. VM cleanup (sx_vm.ml): - Remove temporary debug logging (insn counter, call_closure counter, VmClosure depth tracking) added during debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,13 +84,10 @@ let closure_to_value cl =
|
||||
let _vm_insn_count = ref 0
|
||||
let _vm_call_count = ref 0
|
||||
let _vm_cek_count = ref 0
|
||||
let _vm_closure_call_count = ref 0
|
||||
let _vm_max_depth = ref 0
|
||||
let vm_reset_counters () = _vm_insn_count := 0; _vm_call_count := 0; _vm_cek_count := 0;
|
||||
_vm_closure_call_count := 0; _vm_max_depth := 0
|
||||
let vm_reset_counters () = _vm_insn_count := 0; _vm_call_count := 0; _vm_cek_count := 0
|
||||
let vm_report_counters () =
|
||||
Printf.eprintf "[vm-perf] insns=%d calls=%d cek_fallbacks=%d vm_closure=%d max_depth=%d\n%!"
|
||||
!_vm_insn_count !_vm_call_count !_vm_cek_count !_vm_closure_call_count !_vm_max_depth
|
||||
Printf.eprintf "[vm-perf] insns=%d calls=%d cek_fallbacks=%d\n%!"
|
||||
!_vm_insn_count !_vm_call_count !_vm_cek_count
|
||||
|
||||
(** Push a VM closure frame onto the current VM — no new VM allocation.
|
||||
This is the fast path for intra-VM closure calls. *)
|
||||
@@ -128,9 +125,6 @@ let code_from_value v =
|
||||
Used for entry points: JIT Lambda calls, module execution, cross-boundary. *)
|
||||
let rec call_closure cl args globals =
|
||||
incr _vm_call_count;
|
||||
if !_vm_call_count mod 10000 = 0 then
|
||||
Printf.eprintf "[vm-debug] call_closure count=%d name=%s\n%!"
|
||||
!_vm_call_count (match cl.vm_name with Some n -> n | None -> "anon");
|
||||
let vm = create globals in
|
||||
push_closure_frame vm cl args;
|
||||
(try run vm with e -> raise e);
|
||||
@@ -144,13 +138,6 @@ and vm_call vm f args =
|
||||
match f with
|
||||
| VmClosure cl ->
|
||||
(* Fast path: push frame on current VM — no allocation, enables TCO *)
|
||||
incr _vm_closure_call_count;
|
||||
let depth = List.length vm.frames + 1 in
|
||||
if depth > !_vm_max_depth then _vm_max_depth := depth;
|
||||
if !_vm_closure_call_count mod 100000 = 0 then
|
||||
Printf.eprintf "[vm-debug] VmClosure calls=%d depth=%d name=%s\n%!"
|
||||
!_vm_closure_call_count depth
|
||||
(match cl.vm_name with Some n -> n | None -> "anon");
|
||||
push_closure_frame vm cl args
|
||||
| NativeFn (_name, fn) ->
|
||||
let result = fn args in
|
||||
@@ -202,12 +189,6 @@ and run vm =
|
||||
if frame.ip >= Array.length bc then
|
||||
vm.frames <- [] (* bytecode exhausted — stop *)
|
||||
else begin
|
||||
incr _vm_insn_count;
|
||||
if !_vm_insn_count mod 1000000 = 0 then begin
|
||||
let fn_name = match frame.closure.vm_name with Some n -> n | None -> "?" in
|
||||
Printf.eprintf "[vm-debug] insns=%dM in=%s ip=%d depth=%d sp=%d\n%!"
|
||||
(!_vm_insn_count / 1000000) fn_name frame.ip (List.length vm.frames) vm.sp
|
||||
end;
|
||||
let saved_ip = frame.ip in
|
||||
let op = bc.(frame.ip) in
|
||||
frame.ip <- frame.ip + 1;
|
||||
|
||||
Reference in New Issue
Block a user