Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
345 changes: 335 additions & 10 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"crates/weavepy-cli",
"crates/weavepy-compiler",
"crates/weavepy-conformance",
"crates/weavepy-jit",
"crates/weavepy-lexer",
"crates/weavepy-parser",
"crates/weavepy-vm",
Expand All @@ -29,7 +30,11 @@ default-members = [
[workspace.package]
version = "0.0.0"
edition = "2021"
rust-version = "1.85"
# RFC 0032 — the tier-2 Cranelift JIT (`weavepy-jit`, behind the `jit`
# feature) pulls in Cranelift 0.132, whose MSRV is 1.93. The JIT is
# off by default, but CI builds it via `--all-features`, so the
# workspace floor moves with it.
rust-version = "1.93"
license = "MIT OR Apache-2.0"
repository = "https://github.com/weavefoundry/weavepy"
homepage = "https://github.com/weavefoundry/weavepy"
Expand All @@ -44,6 +49,7 @@ weavepy = { path = "crates/weavepy", version = "0.0.0" }
weavepy-capi = { path = "crates/weavepy-capi", version = "0.0.0" }
weavepy-compiler = { path = "crates/weavepy-compiler", version = "0.0.0" }
weavepy-conformance = { path = "crates/weavepy-conformance", version = "0.0.0" }
weavepy-jit = { path = "crates/weavepy-jit", version = "0.0.0" }
weavepy-lexer = { path = "crates/weavepy-lexer", version = "0.0.0" }
weavepy-parser = { path = "crates/weavepy-parser", version = "0.0.0" }
weavepy-vm = { path = "crates/weavepy-vm", version = "0.0.0" }
Expand Down Expand Up @@ -111,6 +117,15 @@ parking_lot = "0.12"
crossbeam-channel = "0.5"
crossbeam-utils = "0.8"

# RFC 0032 — tier-2 JIT backend (Cranelift). Only compiled when the
# `jit` feature is enabled (off by default); CI exercises it via
# `--all-features`. MSRV floor for these is Rust 1.93.
cranelift-codegen = "0.132"
cranelift-frontend = "0.132"
cranelift-jit = "0.132"
cranelift-module = "0.132"
cranelift-native = "0.132"

# Test/bench-only.
insta = { version = "1.40", features = ["yaml"] }
proptest = "1.5"
Expand Down
5 changes: 5 additions & 0 deletions crates/weavepy-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ weavepy-vm = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

[features]
default = []
# RFC 0032 — run the bench harness with the tier-2 JIT compiled in.
jit = ["weavepy/jit", "weavepy-vm/jit"]

[lints]
workspace = true
35 changes: 35 additions & 0 deletions crates/weavepy-bench/fixtures/jitloop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""While-loop numeric kernel called many times — the fixture the
RFC 0032 tier-2 JIT targets most directly.

`kernel` is a pure integer hot loop (no FOR_ITER, no calls in the
loop body) so it lands in the JITable subset; `bench` calls it `n`
times so the per-`CodeObject` hot counter crosses the tier-up
threshold and the kernel runs as native code for the bulk of the
work. With `WEAVEPY_JIT=0` it measures the interpreter on the same
shape, which is the comparison we care about.
"""

import os


def kernel(n):
s = 0
i = 0
while i < n:
s = s + i * 2 - (i // 3) + (i % 7)
i = i + 1
return s


def bench(n):
total = 0
k = 0
while k < n:
total = total + kernel(n)
k = k + 1
return total


if __name__ == "__main__":
n = int(os.environ.get("WEAVEPY_BENCH_WORK", "300"))
bench(n)
2 changes: 2 additions & 0 deletions crates/weavepy-bench/src/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub const FIXTURES: &[&str] = &[
"richards",
"sumvm",
"nested_loops",
"jitloop",
];

/// Default per-fixture work parameter passed as `bench(n)`.
Expand All @@ -35,6 +36,7 @@ pub fn default_work(name: &str) -> u32 {
"richards" => 1,
"sumvm" => 50_000,
"nested_loops" => 30,
"jitloop" => 300,
_ => 1,
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/weavepy-bench/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ fn cmd_run(args: &[String]) -> io::Result<()> {
// suite. Off by default; cheap when off.
println!();
println!("{}", format_stats_markdown(&snapshot()));
// RFC 0032 — append tier-2 JIT counters when compiled in.
if let Some(jit) = weavepy_vm::jit_stats_markdown() {
println!();
println!("{jit}");
}
}
}
Ok(())
Expand Down
6 changes: 6 additions & 0 deletions crates/weavepy-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,11 @@ dirs = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

[features]
default = []
# RFC 0032 — build the `weavepy` binary with the tier-2 JIT compiled in
# (still gated at runtime by `WEAVEPY_JIT=1`).
jit = ["weavepy/jit", "weavepy-vm/jit"]

[lints]
workspace = true
18 changes: 18 additions & 0 deletions crates/weavepy-compiler/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,24 @@ pub enum InlineCache {
UnpackSequenceTuple,
UnpackSequenceList,
UnpackSequenceTwoTuple,

// CALL family (RFC 0032). `func_id` is the `Rc::as_ptr` fingerprint
// of the called `PyFunction`; `argc` is the (fixed) call-site arity.
/// Plain Python function: exact positional arity, no keywords, no
/// `*args`/`**kwargs`/kw-only/defaults needed, and no cells or
/// closure — so the frame's locals are just the arguments padded
/// with `None`, skipping the whole argument-binding dance.
CallPyExactNoFree {
func_id: u64,
argc: u32,
},
/// Plain Python function with the same exact-arity guarantee but a
/// non-trivial cell/closure layout — still skips argument binding,
/// but builds the frame (and its cells) through `make_frame`.
CallPyExact {
func_id: u64,
argc: u32,
},
}

/// Number of generic dispatches a deopted cache must serve before it
Expand Down
24 changes: 24 additions & 0 deletions crates/weavepy-jit/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "weavepy-jit"
description = "RFC 0032 — tier-2 Cranelift JIT for WeavePy's unboxed numeric frames."
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
authors.workspace = true
readme.workspace = true
keywords.workspace = true
categories.workspace = true
publish = false

[dependencies]
weavepy-compiler = { workspace = true }
cranelift-codegen = { workspace = true }
cranelift-frontend = { workspace = true }
cranelift-jit = { workspace = true }
cranelift-module = { workspace = true }
cranelift-native = { workspace = true }

[lints]
workspace = true
Loading
Loading