Skip to content

Commit 115a8bd

Browse files
committed
docs(jit): codify supported acceleration baseline
1 parent 790d971 commit 115a8bd

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

benchmarks/vm-jit/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ use. Microbenchmark-only wins are insufficient.
4141
Current evidence keeps baseline scalar loops, native call chains, and the shared
4242
Option/Result/Variant scalar-replacement path. Profile-guided closure PIC and
4343
branch-side-exit speculation are isolated behind the VM-only `jit-speculation`
44-
feature. Native recursion is isolated behind `jit-recursion-experimental`.
44+
feature. Native recursion is isolated behind `jit-recursion-experimental`, and
45+
loop-invariant helper memoization behind `jit-memoization-experimental`. The
46+
ordinary SDK `native-jit` feature compiles none of those research implementations.
4547

4648
## Adding a workload
4749

crates/rsscript-sdk/tests/architecture.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,38 @@ fn cranelift_engine_uses_real_modules_instead_of_flattened_includes() {
11971197
}
11981198
}
11991199

1200+
#[test]
1201+
fn cranelift_engine_keeps_research_features_and_raw_abi_out_of_the_stable_surface() {
1202+
let root = workspace_root();
1203+
let manifest = read(&root.join("crates/rsscript-jit-cranelift/Cargo.toml"));
1204+
let library = read(&root.join("crates/rsscript-jit-cranelift/src/lib.rs"));
1205+
let vm_manifest = read(&root.join("crates/rsscript-vm/Cargo.toml"));
1206+
1207+
assert!(manifest.contains("publish = false"));
1208+
for feature in ["speculation = []", "recursion = []", "memoization = []"] {
1209+
assert!(
1210+
manifest.contains(feature),
1211+
"Cranelift manifest is missing isolated research feature `{feature}`"
1212+
);
1213+
}
1214+
assert!(!library.contains("pub use host_abi::*;"));
1215+
assert!(!library.contains("pub use ir::*;"));
1216+
assert!(!library.contains("pub use module::*;"));
1217+
assert!(library.contains("JitCallFrame"));
1218+
assert!(!library.contains("pub use host_abi::{\n JitCallFrame"));
1219+
1220+
let native_jit = vm_manifest
1221+
.lines()
1222+
.find(|line| line.starts_with("native-jit ="))
1223+
.expect("VM must declare the stable native-jit feature");
1224+
assert!(!native_jit.contains("speculation"));
1225+
assert!(!native_jit.contains("recursion"));
1226+
assert!(!native_jit.contains("memoization"));
1227+
assert!(vm_manifest.contains("jit-speculation"));
1228+
assert!(vm_manifest.contains("jit-recursion-experimental"));
1229+
assert!(vm_manifest.contains("jit-memoization-experimental"));
1230+
}
1231+
12001232
fn rust_files_below(root: &Path) -> Vec<PathBuf> {
12011233
fn visit(directory: &Path, files: &mut Vec<PathBuf>) {
12021234
let mut entries = fs::read_dir(directory)

docs/spec/native-jit-contract.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
The native JIT is an optional accelerator for trusted, in-process execution. It
44
does not add an isolation boundary and never changes Provider authority.
55

6+
The supported `native-jit` feature is intentionally a bounded *feature surface*,
7+
not yet an accelerator for bounded executions. Whole-function native entry
8+
currently declines when step, cancellation, deadline, allocation, live-memory,
9+
intrinsic-call, or Provider-call limits are armed. The interpreter then executes
10+
the request with the original limits. This fail-closed behavior keeps ordinary
11+
bounded execution correct; hosts only receive native acceleration from the
12+
explicit trusted/unbounded execution mode until accounting parity is implemented.
13+
614
## Stable invariants
715

816
- The interpreter is the semantic oracle. Unsupported operations and guarded
@@ -25,6 +33,11 @@ does not add an isolation boundary and never changes Provider authority.
2533
deoptimization, and OSR eligibility are classified by the exhaustive
2634
`JitInstr::effects` API. Validators and tiering must consume those facts rather
2735
than maintain independent opcode lists.
36+
- Structural compilation work is bounded by `JitLimits` before Cranelift code
37+
generation. Instruction, register, CFG-edge, operand, analysis-word, deopt,
38+
memo-scope, callee, and recursive-group counts have deterministic limits.
39+
`max_compile_millis` is a soft admission/telemetry limit, not a claim that an
40+
in-process Cranelift invocation can be interrupted at a wall-clock deadline.
2841

2942
## Internal contracts
3043

@@ -41,6 +54,21 @@ Profile-guided closure PIC and branch-side-exit speculation are excluded from th
4154
stable SDK path. They remain behind the VM-only `jit-speculation` research feature
4255
until a canonical compiler workload demonstrates a repeatable end-to-end benefit.
4356

57+
Loop-invariant host-helper memoization is likewise excluded from the stable SDK
58+
path and compiled only by `jit-memoization-experimental`. Its CFG scope proof and
59+
runtime memo state must earn retention through the same canonical scorecard.
60+
61+
The Cranelift engine crate is not independently published. Its public root exposes
62+
only the VM-facing engine, validated IR, typed options/outcomes, host-helper
63+
contract, and prepared-call boundary. Raw call-frame layout, ABI offsets, helper
64+
function aliases, codegen internals, and module implementation types remain
65+
crate-private.
66+
67+
Native rewrites carry `NativeInstructionOrigin { bytecode_ip, resume_ip }` in one
68+
owned pipeline state. A pass may temporarily return a local new-to-previous map,
69+
but only the pipeline state composes it; source and deopt-resume identity may not
70+
travel in unrelated parallel vectors.
71+
4472
## Native recursion
4573

4674
Tail recursion may be lowered to a loop. Non-tail self or group recursion uses the
@@ -62,3 +90,10 @@ deoptimization and rollback cases, 64/128/256 KiB host-stack entries, guard-page
6290
flat-buffer bounds tests, AddressSanitizer coverage for host wrappers, structured
6391
IR fuzzing, and the workload scorecard. ASan does not instrument generated machine
6492
code; guard pages and canary/boundary fixtures cover direct native memory accesses.
93+
94+
The stable retention set is baseline scalar/flat-data execution, native leaf-call
95+
chains, transactional helpers, precise deopt, and the Option/Result/Variant scalar
96+
replacement paths that enter on the canonical scorecard. Speculation, non-tail
97+
native recursion, and helper memoization are research features. A local scorecard
98+
run is diagnostic only; timings become a compatibility or release signal only
99+
after a controlled-hardware baseline is checked in with machine/toolchain metadata.

0 commit comments

Comments
 (0)