Initial jit prototype.

This commit is contained in:
Ben Lewis committed 2020-08-25 07:16:58 +12:00
1 parent 809816cc23
commit b2ab9d9bdf
6 files changed
+352 -1

No files matched your search

Generated
+229
View File
@@ -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
View File
@@ -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"
+14
View File
@@ -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"
+92
View File
@@ -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]")
}
}
+1
View File
@@ -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"
+15
View File
@@ -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")]