mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Initial jit prototype.
This commit is contained in:
1 parent
809816cc23
commit
b2ab9d9bdf
6 files changed
+352
-1
No files matched your search
Generated
+229
@@ -36,6 +36,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
|
||||
|
||||
[[package]]
|
||||
name = "arr_macro"
|
||||
version = "0.1.3"
|
||||
@@ -289,6 +295,117 @@ dependencies = [
|
||||
"python3-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fc21c925da7fbb64597c86521b59726426fb660ad30f898a01b957f39d15558"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-frontend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dcc286b052ee24a1e5a222e7c1125e6010ad35b0f248709b9b3737a8fedcfdf"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d9badfe36176cb653506091693bc2bb1970c9bddfcd6ec7fac404f7eaec6f38"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-meta",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
"log",
|
||||
"regalloc",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3f460031861e4f4ad510be62b2ae50bba6cc886b598a36f9c0a970feab9598"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ad12409e922e7697cd0bdc7dc26992f64a77c31880dfe5e3c7722f4710206d"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d97cdc58972ea065d107872cfb9079f4c92ade78a8af85aaff519a65b5d13f71"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ef419efb4f94ecc02e5d9fbcc910d2bb7f0040e2de570e63a454f883bc891d6"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "001d9b320ce30999c618db554ae9b23ec16d410493a502be674e2ef146bbdf0d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-entity",
|
||||
"log",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e69d44d59826eef6794066ac2c0f4ad3975f02d97030c60dbc04e3886adf36e"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"raw-cpuid",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-simplejit"
|
||||
version = "0.66.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7506acda1b0df5419e8de5f1706cfcd8779d3d40d70c179f361e647fe9b18f0"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"errno",
|
||||
"libc",
|
||||
"region",
|
||||
"target-lexicon",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
@@ -459,6 +576,27 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exitcode"
|
||||
version = "1.1.2"
|
||||
@@ -547,6 +685,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
@@ -779,6 +923,15 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "761104bf97f13a3caf47d822498a0760a10d00d220148bac2669f63fc3bb8270"
|
||||
|
||||
[[package]]
|
||||
name = "mach"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
@@ -1180,6 +1333,17 @@ dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "7.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
@@ -1197,6 +1361,17 @@ dependencies = [
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regalloc"
|
||||
version = "0.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9ba8aaf5fe7cf307c6dbdaeed85478961d29e25e3bee5169e11b92fa9f027a8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
@@ -1224,6 +1399,18 @@ version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
|
||||
[[package]]
|
||||
name = "region"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"mach",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "result-like"
|
||||
version = "0.2.1"
|
||||
@@ -1245,6 +1432,12 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
@@ -1338,6 +1531,15 @@ dependencies = [
|
||||
"syn-ext",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-jit"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"cranelift",
|
||||
"cranelift-module",
|
||||
"cranelift-simplejit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.1.2"
|
||||
@@ -1422,6 +1624,7 @@ dependencies = [
|
||||
"rustpython-common",
|
||||
"rustpython-compiler",
|
||||
"rustpython-derive",
|
||||
"rustpython-jit",
|
||||
"rustpython-parser",
|
||||
"rustpython-pylib",
|
||||
"rustyline",
|
||||
@@ -1692,6 +1895,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.5.2"
|
||||
@@ -1721,6 +1930,26 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "3.3.0"
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ license = "MIT"
|
||||
include = ["LICENSE", "Cargo.toml", "src/**/*.rs"]
|
||||
|
||||
[workspace]
|
||||
members = [".", "derive", "vm", "wasm/lib", "parser", "compiler", "bytecode", "vm/pylib-crate", "common"]
|
||||
members = [".", "derive", "vm", "wasm/lib", "parser", "compiler", "bytecode", "vm/pylib-crate", "common", "jit"]
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "rustpython-jit"
|
||||
version = "0.1.2"
|
||||
description = "Experimental JIT(just in time) compiler for python code."
|
||||
authors = [ "RustPython Team" ]
|
||||
repository = "https://github.com/RustPython/RustPython"
|
||||
license = "MIT"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
cranelift = "0.66.0"
|
||||
cranelift-module = "0.66.0"
|
||||
cranelift-simplejit = "0.66.0"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
||||
use cranelift::prelude::*;
|
||||
use cranelift_module::{Backend, Module, Linkage, FuncId};
|
||||
use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
|
||||
|
||||
|
||||
struct JIT {
|
||||
builder_context: FunctionBuilderContext,
|
||||
ctx: codegen::Context,
|
||||
module: Module<SimpleJITBackend>,
|
||||
}
|
||||
|
||||
impl JIT {
|
||||
fn new() -> Self {
|
||||
let builder = SimpleJITBuilder::new(cranelift_module::default_libcall_names());
|
||||
let module = Module::new(builder);
|
||||
Self {
|
||||
builder_context: FunctionBuilderContext::new(),
|
||||
ctx: module.make_context(),
|
||||
module,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_function(&mut self) -> FuncId {
|
||||
let id = self
|
||||
.module
|
||||
.declare_function("jitted", Linkage::Export, &self.ctx.func.signature)
|
||||
.unwrap();
|
||||
|
||||
let mut builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_context);
|
||||
let entry_block = builder.create_block();
|
||||
// builder.append_block_params_for_function_params(entry_block);
|
||||
builder.switch_to_block(entry_block);
|
||||
// builder.seal_block(entry_block);
|
||||
builder.ins().return_(&[]);
|
||||
builder.finalize();
|
||||
|
||||
self.module
|
||||
.define_function(id, &mut self.ctx, &mut codegen::binemit::NullTrapSink {})
|
||||
.unwrap();
|
||||
|
||||
self.module.clear_context(&mut self.ctx);
|
||||
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile() -> CompiledCode {
|
||||
|
||||
let mut jit = JIT::new();
|
||||
|
||||
let id = jit.build_function();
|
||||
|
||||
jit.module.finalize_definitions();
|
||||
|
||||
let code = jit.module.get_finalized_function(id);
|
||||
CompiledCode {
|
||||
code,
|
||||
memory: jit.module.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CompiledCode {
|
||||
code: *const u8,
|
||||
memory: <SimpleJITBackend as Backend>::Product
|
||||
}
|
||||
|
||||
impl CompiledCode {
|
||||
pub fn invoke(&self) {
|
||||
let func = unsafe { mem::transmute::<_, fn()>(self.code) };
|
||||
func()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for CompiledCode {}
|
||||
|
||||
impl Drop for CompiledCode {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: The only pointer that this memory will also be dropped now
|
||||
unsafe {
|
||||
self.memory.free_memory()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CompiledCode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("[compiled code]")
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ rustpython-derive = { path = "../derive", version = "0.1.2" }
|
||||
rustpython-parser = { path = "../parser", optional = true, version = "0.1.2" }
|
||||
rustpython-compiler = { path = "../compiler", optional = true, version = "0.1.2" }
|
||||
rustpython-bytecode = { path = "../bytecode", version = "0.1.2" }
|
||||
rustpython-jit = { path = "../jit", version = "0.1.2" }
|
||||
rustpython-pylib = { path = "pylib-crate", optional = true, version = "0.1.0" }
|
||||
serde = { version = "1.0.66", features = ["derive"] }
|
||||
byteorder = "1.2.6"
|
||||
|
||||
@@ -17,6 +17,8 @@ use crate::scope::Scope;
|
||||
use crate::slots::{SlotCall, SlotDescriptor};
|
||||
use crate::VirtualMachine;
|
||||
use itertools::Itertools;
|
||||
use rustpython_common::cell::PyMutex;
|
||||
use rustpython_jit::CompiledCode;
|
||||
|
||||
pub type PyFunctionRef = PyRef<PyFunction>;
|
||||
|
||||
@@ -24,6 +26,7 @@ pub type PyFunctionRef = PyRef<PyFunction>;
|
||||
#[derive(Debug)]
|
||||
pub struct PyFunction {
|
||||
code: PyCodeRef,
|
||||
jitted_code: PyMutex<Option<CompiledCode>>,
|
||||
scope: Scope,
|
||||
defaults: Option<PyTupleRef>,
|
||||
kw_only_defaults: Option<PyDictRef>,
|
||||
@@ -54,6 +57,7 @@ impl PyFunction {
|
||||
) -> Self {
|
||||
PyFunction {
|
||||
code,
|
||||
jitted_code: PyMutex::new(None),
|
||||
scope,
|
||||
defaults,
|
||||
kw_only_defaults,
|
||||
@@ -223,6 +227,11 @@ impl PyFunction {
|
||||
scope: &Scope,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
if let Some(jitted_code) = &*self.jitted_code.lock() {
|
||||
jitted_code.invoke();
|
||||
return Ok(vm.get_none());
|
||||
}
|
||||
|
||||
let code = &self.code;
|
||||
|
||||
let scope = if self.code.flags.contains(bytecode::CodeFlags::NEW_LOCALS) {
|
||||
@@ -285,6 +294,12 @@ impl PyFunction {
|
||||
fn globals(&self) -> PyDictRef {
|
||||
self.scope.globals.clone()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn jit(&self) {
|
||||
let mut guard = self.jitted_code.lock();
|
||||
*guard = Some(rustpython_jit::compile());
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(module = false, name = "method")]
|
||||
|
||||
Reference in new issue
Block a user