Fix JIT infinite recompile loop for closure functions

When a JIT-compiled function failed on first call, the function name
was added to _jit_warned but this was never checked before recompiling.
Closures like parse-loop create new lambda instances on each call,
each with l_compiled=None, triggering fresh compilation + failure
in an infinite loop.

Fix: check _jit_warned before attempting compilation, and mark the
lambda with jit_failed_sentinel on first-call failure so the same
instance also stops retrying.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 19:37:12 +00:00
parent 6a4b2d9a33
commit 4dde8ba684

View File

@@ -727,7 +727,7 @@ let register_jit_hook env =
None)
| Some _ -> None (* compile failed or disabled — CEK handles *)
| None ->
if !_jit_compiling then None
if !_jit_compiling || Hashtbl.mem _jit_warned fn_name then None
else begin
_jit_compiling := true;
let t0 = Unix.gettimeofday () in
@@ -742,6 +742,7 @@ let register_jit_hook env =
(try Some (Sx_vm.call_closure cl args cl.vm_env_ref)
with e ->
Printf.eprintf "[jit] %s first-call fallback to CEK: %s\n%!" fn_name (Printexc.to_string e);
l.l_compiled <- Some Sx_vm.jit_failed_sentinel;
Hashtbl.replace _jit_warned fn_name true;
None)
| None -> None