Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add new AOT mode to replace experimental JIT mode #72

Merged
merged 8 commits into from
Jun 20, 2019
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
6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ build = "build.rs"
[features]
default = []

asm = ["libc"]

jit = ["fnv", "memmap", "libc"]
asm = ["libc", "memmap"]

[dependencies]
byteorder = "1"
bytes = "0.4.12"
goblin = "0.0.22"
fnv = { version = "1.0.6", optional = true }
hashbrown = "0.5.0"
memmap = { version = "0.7.0", optional = true }
libc = { version = "0.2.47", optional = true }
ckb-vm-definitions = { path = "definitions", version = "0.13.0" }
Expand Down
14 changes: 6 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ test:
cargo test --all -- --nocapture

test-all-features:
cargo test --all --features=jit,asm -- --nocapture
cargo test --all --features=asm -- --nocapture

# JIT code is considered experimental right now, hence coverage
# would skip it.
cov:
cargo clean
cargo test --all --features=asm -- --nocapture
Expand All @@ -16,7 +14,7 @@ fmt:
cd definitions && cargo fmt ${VERBOSE} --all -- --check

clippy:
cargo clippy --all --features=jit,asm -- -D warnings -D clippy::clone_on_ref_ptr -D clippy::enum_glob_use -A clippy::inconsistent_digit_grouping -A clippy::large-digit-groups
cargo clippy --all --features=asm -- -D warnings -D clippy::clone_on_ref_ptr -D clippy::enum_glob_use -A clippy::inconsistent_digit_grouping -A clippy::large-digit-groups
cd definitions && cargo clippy --all -- -D warnings -D clippy::clone_on_ref_ptr -D clippy::enum_glob_use -A clippy::inconsistent_digit_grouping -A clippy::large-digit-groups

ci: fmt clippy test
Expand All @@ -28,8 +26,8 @@ ci-quick: test
ci-all-features: test-all-features
git diff --exit-code Cargo.lock

ci-generated: src/jit/asm.x64.compiled.c update-cdefinitions
git diff --exit-code src/jit/asm.x64.compiled.c src/machine/asm/cdefinitions_generated.h
ci-generated: src/machine/aot/aot.x64.compiled.c update-cdefinitions
git diff --exit-code src/machine/aot/aot.x64.compiled.c src/machine/asm/cdefinitions_generated.h

# For counting lines of code
stats:
Expand All @@ -46,7 +44,7 @@ update-cdefinitions:
cargo run --manifest-path=definitions/Cargo.toml --bin generate_asm_constants > src/machine/asm/cdefinitions_generated.h

# Following rules are used to update dynasm compiled files
src/jit/asm.x64.compiled.c: src/jit/asm.x64.c .deps/luajit/src/host/minilua
src/machine/aot/aot.x64.compiled.c: src/machine/aot/aot.x64.c .deps/luajit/src/host/minilua
.deps/luajit/src/host/minilua .deps/luajit/dynasm/dynasm.lua -o $@ $<

.deps/luajit/src/host/minilua:
Expand All @@ -56,6 +54,6 @@ src/jit/asm.x64.compiled.c: src/jit/asm.x64.c .deps/luajit/src/host/minilua
make

.PHONY: test clippy fmt
.PHONY: ci ci-quick ci-jit ci-asm ci-cdefinitions
.PHONY: ci ci-quick ci-all-features ci-cdefinitions
.PHONY: stats security-audit
.PHONY: update-cdefinitions
33 changes: 11 additions & 22 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,20 @@
// specify different features based on different targets now in cargo file. We
// have to keep features always on, and do conditional compilation within the
// source code
#[cfg(all(
unix,
target_pointer_width = "64",
any(feature = "asm", feature = "jit")
))]
#[cfg(all(unix, target_pointer_width = "64", feature = "asm"))]
use cc::Build;

#[cfg(all(unix, target_pointer_width = "64", feature = "asm"))]
fn main() {
#[cfg(all(
unix,
target_pointer_width = "64",
any(feature = "asm", feature = "jit")
))]
let mut build = Build::new();

#[cfg(all(unix, target_pointer_width = "64", feature = "asm"))]
build.file("src/machine/asm/execute.S");

#[cfg(all(unix, target_pointer_width = "64", feature = "jit"))]
build.file("src/jit/asm.x64.compiled.c").include("dynasm");

#[cfg(all(
unix,
target_pointer_width = "64",
any(feature = "asm", feature = "jit")
))]
build.compile("asm");
build
.file("src/machine/asm/execute.S")
.file("src/machine/aot/aot.x64.compiled.c")
.include("dynasm")
.include("src/machine/asm")
.compile("asm");
}

#[cfg(not(all(unix, target_pointer_width = "64", feature = "asm")))]
fn main() {}
7 changes: 4 additions & 3 deletions definitions/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ pub const TRACE_ITEM_LENGTH: usize = 16;
pub const RET_DECODE_TRACE: u8 = 1;
pub const RET_ECALL: u8 = 2;
pub const RET_EBREAK: u8 = 3;
pub const RET_MAX_CYCLES_EXCEEDED: u8 = 4;
pub const RET_OUT_OF_BOUND: u8 = 5;
pub const RET_INVALID_PERMISSION: u8 = 6;
pub const RET_DYNAMIC_JUMP: u8 = 4;
pub const RET_MAX_CYCLES_EXCEEDED: u8 = 5;
pub const RET_OUT_OF_BOUND: u8 = 6;
pub const RET_INVALID_PERMISSION: u8 = 7;

#[inline(always)]
pub fn calculate_slot(addr: u64) -> usize {
Expand Down
5 changes: 3 additions & 2 deletions definitions/src/generate_asm_constants.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ckb_vm_definitions::{
asm::{
AsmCoreMachine, Trace, RET_DECODE_TRACE, RET_EBREAK, RET_ECALL, RET_INVALID_PERMISSION,
RET_MAX_CYCLES_EXCEEDED, RET_OUT_OF_BOUND, TRACE_ITEM_LENGTH,
AsmCoreMachine, Trace, RET_DECODE_TRACE, RET_DYNAMIC_JUMP, RET_EBREAK, RET_ECALL,
RET_INVALID_PERMISSION, RET_MAX_CYCLES_EXCEEDED, RET_OUT_OF_BOUND, TRACE_ITEM_LENGTH,
},
instructions::{Instruction, INSTRUCTION_OPCODE_NAMES},
memory::{FLAG_EXECUTABLE, FLAG_FREEZED, FLAG_WRITABLE, FLAG_WXORX_BIT},
Expand Down Expand Up @@ -34,6 +34,7 @@ fn main() {
println!("#define CKB_VM_ASM_RET_DECODE_TRACE {}", RET_DECODE_TRACE);
println!("#define CKB_VM_ASM_RET_ECALL {}", RET_ECALL);
println!("#define CKB_VM_ASM_RET_EBREAK {}", RET_EBREAK);
println!("#define CKB_VM_ASM_RET_DYNAMIC_JUMP {}", RET_DYNAMIC_JUMP);
println!(
"#define CKB_VM_ASM_RET_MAX_CYCLES_EXCEEDED {}",
RET_MAX_CYCLES_EXCEEDED
Expand Down
29 changes: 25 additions & 4 deletions src/jit/value.rs → src/instructions/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use super::machine::MemorySize;
use crate::Register;
use std::fmt::{self, Display};
use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
Expand Down Expand Up @@ -41,7 +40,7 @@ pub enum Value {
Op2(ActionOp2, Rc<Value>, Rc<Value>),
SignOp2(SignActionOp2, Rc<Value>, Rc<Value>, bool),
Cond(Rc<Value>, Rc<Value>, Rc<Value>),
Load(Rc<Value>, MemorySize),
Load(Rc<Value>, u8),
}

impl Default for Value {
Expand All @@ -60,6 +59,9 @@ impl Not for Value {
type Output = Self;

fn not(self) -> Value {
if let Value::Imm(imm) = self {
return Value::Imm(!imm);
}
Value::Op1(ActionOp1::Not, Rc::new(self))
}
}
Expand All @@ -68,6 +70,9 @@ impl BitAnd for Value {
type Output = Self;

fn bitand(self, rhs: Self) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
return Value::Imm(imm1 & imm2);
}
Value::Op2(ActionOp2::Bitand, Rc::new(self), Rc::new(rhs))
}
}
Expand All @@ -76,6 +81,9 @@ impl BitOr for Value {
type Output = Self;

fn bitor(self, rhs: Self) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
return Value::Imm(imm1 | imm2);
}
Value::Op2(ActionOp2::Bitor, Rc::new(self), Rc::new(rhs))
}
}
Expand All @@ -84,6 +92,9 @@ impl BitXor for Value {
type Output = Self;

fn bitxor(self, rhs: Self) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
return Value::Imm(imm1 ^ imm2);
}
Value::Op2(ActionOp2::Bitxor, Rc::new(self), Rc::new(rhs))
}
}
Expand All @@ -92,6 +103,10 @@ impl Shl<Value> for Value {
type Output = Self;

fn shl(self, rhs: Self) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
// By default immediates are unsigned
return Value::Imm(imm1 << imm2);
}
Value::Op2(ActionOp2::Shl, Rc::new(self), Rc::new(rhs))
}
}
Expand All @@ -100,6 +115,10 @@ impl Shr<Value> for Value {
type Output = Self;

fn shr(self, rhs: Self) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
// By default immediates are unsigned
return Value::Imm(imm1 >> imm2);
}
Value::SignOp2(SignActionOp2::Shr, Rc::new(self), Rc::new(rhs), false)
}
}
Expand Down Expand Up @@ -160,8 +179,6 @@ impl Register for Value {
}

fn overflowing_add(&self, rhs: &Value) -> Value {
// This is a very naive constant elimination optimization
// served as a PoC purpose
if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
let imm = (*imm1).overflowing_add(*imm2).0;
return Value::Imm(imm);
Expand Down Expand Up @@ -249,6 +266,10 @@ impl Register for Value {
}

fn signed_shr(&self, rhs: &Value) -> Value {
if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
// By default immediates are unsigned
return Value::Imm(((*imm1 as i64) >> imm2) as u64);
}
Value::SignOp2(
SignActionOp2::Shr,
Rc::new(self.clone()),
Expand Down
4 changes: 3 additions & 1 deletion src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ mod execute;
mod register;
mod utils;

pub mod ast;
pub mod i;
pub mod m;
pub mod rvc;

pub use self::register::Register;
use super::Error;
pub use ckb_vm_definitions::instructions::{
self as insts, Instruction, InstructionOpcode, MAXIMUM_RVC_OPCODE, MINIMAL_RVC_OPCODE,
self as insts, Instruction, InstructionOpcode, INSTRUCTION_OPCODE_NAMES, MAXIMUM_RVC_OPCODE,
MINIMAL_RVC_OPCODE,
};
pub use execute::execute;

Expand Down
Loading