host: fix serving-JIT host miscompile — install IO resolver for http-listen
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s

The serving-JIT perform-in-HO-callback miscompile (map/rest/drop wrong
CALL_PRIM args → blank pages, empty picker) is now fully fixed, so the host
runs 100% serving JIT with NO jit-exclude.

sx-vm-extensions 81177d0e resolves a suspended HO-callback's IO inline
(instead of unwinding the native map/filter loop and corrupting the stack),
but ONLY when a synchronous resolver is installed (!_cek_io_resolver = Some).
The host serves via the http-listen primitive, whose handler drove durable IO
through cek_run_with_io with the resolver = None — so it hit the unwinding
path the fix doesn't cover. (The vm-ext repro installed a resolver, so it
never exercised the host's real no-resolver path.)

Fix: extract cek_run_with_io's IO resolution into resolve_io_request, and have
http-listen install _cek_io_resolver := Some (fun req _ -> resolve_io_request
req) — byte-identical resolution, so the inline path resolves durable reads
exactly as the CEK loop would.

Verified: host conformance 271/271; ephemeral durable server at 100% JIT (no
exclude) zero fallbacks + real content + related shown + picker 12 candidates;
live blog.rose-ash.com home/post/tags 200 with related posts, zero error-log
lines; relate-picker Playwright 4/4 (infinite-scroll + filter + relate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 20:13:24 +00:00
parent 8104aadc2b
commit d8d7663565
3 changed files with 102 additions and 59 deletions

View File

@@ -1,5 +1,34 @@
# Hand-off: serving-mode JIT miscompiles host handlers (to sx-vm-extensions)
> ## ✅ RESOLVED 2026-06-28 — host now runs 100% serving JIT, no exclude.
>
> Two composing pieces fixed it:
> 1. **sx-vm-extensions `81177d0e`** (`sx_vm.ml` `call_closure_reuse`): when an
> HO-primitive callback (map/filter/reduce/…) suspends on a `perform` AND a
> synchronous resolver is installed, resolve its IO inline and run it to
> completion instead of unwinding the native loop (which dropped iteration
> state and misaligned the stack → the next `CALL_PRIM` got wrong args).
> 2. **host side (`sx_server.ml`)**: that fix only engages when
> `!_cek_io_resolver = Some`. The host serves via the `http-listen` primitive,
> whose handler drove durable IO through `cek_run_with_io` with the resolver
> **= None**, so it hit the unwinding path the fix doesn't cover (the
> vm-extensions repro `repro_jit_resume.ml` *installed* a resolver, so it never
> exercised the host's real path). Fix: extracted `cek_run_with_io`'s IO
> resolution into `resolve_io_request`, and `http-listen` now installs
> `_cek_io_resolver := Some (fun req _ -> resolve_io_request req)` — byte-
> identical resolution, so the inline-resolve path resolves durable reads
> exactly as the CEK loop would.
>
> Verified: host conformance **271/271**; ephemeral durable server at 100% JIT
> (no exclude) — zero fallbacks, real content, related posts shown, picker lists
> 12 candidates; live blog.rose-ash.com home/post/tags 200 with related posts and
> zero error-log lines; relate-picker Playwright **4/4** (infinite-scroll +
> filter + relate, the `drop` path). `serve.sh` exclude dropped.
>
> Everything below is the original hand-off, kept for the record.
---
> From the **host-on-sx** loop, 2026-06-28. We enabled `SX_SERVING_JIT=1` on the
> live host (blog.rose-ash.com) — the Datalog/relations saturation JITs cleanly
> and is the real win (host conformance 271/271 under JIT, 5.4× faster; live