You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Attempted the output-side complement to the input-side array bridge
(commit 927f75c). Goal: let a JIT'd fn return an array via an
`@jit_returns_array_int` pragma that triggers an `omc_arr_heapify`
call before Op::Return, copying the frame-array buffer to heap so it
outlives the JIT'd fn frame. The dispatch boundary materializes the
returned heap pointer as a Value::Array and calls omc_arr_free.
Infrastructure now in place (all builds clean, all 145 OMC tests +
48 codegen tests still pass):
- `CompiledFunction.pragmas: Vec<String>` — bytecode now forwards
source-level @pragma decorators (used by no_heal_* in the heal pass;
now also reachable from codegen for JIT pragmas)
- `JittedFn.returns_array_int: bool` — set by jit_module when the
source fn carries @jit_returns_array_int
- `omc_arr_heapify(frame_ptr) -> i64` extern Rust helper — registered
via add_global_mapping so JIT'd code can call it
- `omc_arr_free(heap_ptr)` extern Rust helper — pub so the dispatch
in main.rs can free the heap allocation after materialization
- Dispatch closure materializer in omnimcode-cli/src/main.rs — when
jf.returns_array_int is true, treats the i64 return as a heap
pointer to [len, v0, ..., vN] and materializes Value::Array
What's NOT working: the codegen path that would call omc_arr_heapify
before Op::Return is DISABLED in dual_band.rs. End-to-end testing
showed heapify runs and returns a valid heap pointer, but the JIT'd
fn segfaults on its `ret` instruction AFTER heapify completes. Cause
not yet understood — stack alignment? extern "C" calling convention
mismatch? alloca lifetime crossing the return? The infrastructure
is left wired so that re-enabling the codegen path is one localized
change (remove the bypass in dual_band.rs Op::Return arm).
Cost of leaving it disabled: zero measurable today. None of the
current harmonic libraries' hot paths return arrays — ha.top_k,
ha.score_all, ha.new are called O(1) per fit, not per row. The
1.9x speedup on harmonic_anomaly from the input-side bridge
(commit 927f75c) stands as the actual user-facing L1.6 win.
docs/jit_real_world.md updated with the honest gap statement under
"Honest limits remaining."
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-**Read-only contract**: the bridge doesn't write back to the original `HArray` even if the JIT'd fn mutated the buffer. Common case (sum, score, count) is read-only; mutating-array fns return `i64` today so output-side bridging is a future extension.
136
136
-**Int-only arrays**: `Value::Array` whose elements aren't all `HInt` (or `Bool`) falls through to tree-walk. String / float arrays are next-session work.
137
-
-**Return values still i64**: a JIT'd fn that wants to return an array would need a result-buffer convention. Not needed by any current harmonic library.
137
+
-**Return-side bridge: infrastructure in place, codegen path disabled.** The wiring went in for an `@jit_returns_array_int` pragma that would call `omc_arr_heapify` before `Op::Return` (copying the frame-array buffer to heap so it outlives the JIT'd fn frame). The Rust extern + global-mapping + JittedFn flag + dispatch materializer + `omc_arr_free` are all present and pass their unit-test paths. But in end-to-end testing the JIT'd fn segfaults on its `ret` instruction AFTER `omc_arr_heapify` successfully runs and returns a valid heap pointer. The trip back through the extern-"C" boundary corrupts something (stack alignment? calling convention? alloca lifetime?). The codegen path is left disabled in `dual_band.rs` so the infrastructure can be re-enabled atomically once the segfault is understood. None of the current harmonic libraries' hot paths return arrays, so this gap costs no measurable performance today — `ha.top_k` / `ha.score_all` / `ha.new` are called O(1) times per fit, not per-row.
0 commit comments