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
4 changes: 2 additions & 2 deletions .github/workflows/develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
ln -snf .. ckb-vm-test-suite/ckb-vm
docker run --rm -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20210804 cp -r /riscv /code/riscv
cd ckb-vm-test-suite
git checkout 898edc351eeb4de974ca4f0ff8d1e4943a95aecb
git checkout 6082bb2710615297f3a9fec95629636e146882c8
git submodule update --init --recursive
RISCV=`pwd`/../riscv ./test.sh
Expand Down Expand Up @@ -136,7 +136,7 @@ jobs:
ln -snf .. ckb-vm-test-suite/ckb-vm
docker run --rm -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20210804 cp -r /riscv /code/riscv
cd ckb-vm-test-suite
git checkout 898edc351eeb4de974ca4f0ff8d1e4943a95aecb
git checkout 6082bb2710615297f3a9fec95629636e146882c8
git submodule update --init --recursive
RISCV=`pwd`/../riscv ./test.sh --build-only
cd ..
Expand Down
6 changes: 3 additions & 3 deletions benches/vm_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bytes::Bytes;
use ckb_vm::{
machine::{
asm::{AsmCoreMachine, AsmMachine},
DefaultMachineBuilder, VERSION0, VERSION2,
DefaultMachineBuilder, DefaultMachineRunner, SupportMachine, VERSION0, VERSION2,
},
ISA_B, ISA_IMC, ISA_MOP,
};
Expand Down Expand Up @@ -40,7 +40,7 @@ fn asm_benchmark(c: &mut Criterion) {
"bar",
].into_iter().map(|a| Ok(a.into()));
b.iter(|| {
let asm_core = AsmCoreMachine::new(ISA_IMC, VERSION0, u64::MAX);
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new(ISA_IMC, VERSION0, u64::MAX);
let core = DefaultMachineBuilder::new(asm_core).build();
let mut machine = AsmMachine::new(core);
machine.load_program(&buffer, args.clone()).unwrap();
Expand All @@ -61,7 +61,7 @@ fn mop_benchmark(c: &mut Criterion) {
"bar",
].into_iter().map(|a| Ok(a.into()));
b.iter(|| {
let asm_core = AsmCoreMachine::new(ISA_IMC | ISA_B | ISA_MOP, VERSION2, u64::MAX);
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new(ISA_IMC | ISA_B | ISA_MOP, VERSION2, u64::MAX);
let core = DefaultMachineBuilder::<Box<AsmCoreMachine>>::new(asm_core)
.build();
let mut machine = AsmMachine::new(core);
Expand Down
61 changes: 2 additions & 59 deletions definitions/src/asm.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::{
instructions::Instruction, MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_SHIFTS,
RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGES, RISCV_PAGESIZE,
instructions::Instruction, MEMORY_FRAMES, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY,
RISCV_PAGES,
};
use std::alloc::{alloc, Layout};

// The number of trace items to keep
pub const TRACE_SIZE: usize = 8192;
Expand Down Expand Up @@ -67,59 +66,3 @@ pub struct AsmCoreMachine {

pub memory: [u8; RISCV_MAX_MEMORY],
}

impl AsmCoreMachine {
pub fn new(isa: u8, version: u32, max_cycles: u64) -> Box<AsmCoreMachine> {
Self::new_with_memory(isa, version, max_cycles, RISCV_MAX_MEMORY)
}

pub fn new_with_memory(
isa: u8,
version: u32,
max_cycles: u64,
memory_size: usize,
) -> Box<AsmCoreMachine> {
assert_ne!(memory_size, 0);
assert_eq!(memory_size % RISCV_PAGESIZE, 0);
assert_eq!(memory_size % (1 << MEMORY_FRAME_SHIFTS), 0);

let mut machine = unsafe {
let machine_size =
std::mem::size_of::<AsmCoreMachine>() - RISCV_MAX_MEMORY + memory_size;

let layout = Layout::array::<u8>(machine_size).unwrap();
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
Box::from_raw(raw_allocation)
};
machine.registers = [0; RISCV_GENERAL_REGISTER_NUMBER];
machine.pc = 0;
machine.next_pc = 0;
machine.running = 0;
machine.cycles = 0;
machine.max_cycles = max_cycles;
if cfg!(feature = "enable-chaos-mode-by-default") {
machine.chaos_mode = 1;
} else {
machine.chaos_mode = 0;
}
machine.chaos_seed = 0;
machine.load_reservation_address = u64::MAX;
machine.reset_signal = 0;
machine.version = version;
machine.isa = isa;
machine.flags = [0; RISCV_PAGES];
for i in 0..TRACE_SIZE {
machine.traces[i] = Trace::default();
}
machine.frames = [0; MEMORY_FRAMES];

machine.memory_size = memory_size as u64;
machine.frames_size = (memory_size / MEMORY_FRAMESIZE) as u64;
machine.flags_size = (memory_size / RISCV_PAGESIZE) as u64;

machine.last_read_frame = u64::MAX;
machine.last_write_page = u64::MAX;

machine
}
}
11 changes: 10 additions & 1 deletion definitions/src/generate_asm_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ckb_vm_definitions::{
MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_PAGE_SHIFTS, MEMORY_FRAME_SHIFTS,
RISCV_MAX_MEMORY, RISCV_PAGES, RISCV_PAGESIZE, RISCV_PAGE_SHIFTS,
};
use std::alloc::{alloc, Layout};
use std::mem::{size_of, zeroed};

macro_rules! print_inst_label {
Expand Down Expand Up @@ -120,7 +121,15 @@ fn main() {
);
println!();

let m: Box<AsmCoreMachine> = AsmCoreMachine::new(0, 0, 0);
// We don't need a fully initialized AsmCoreMachine, only a dummy
// structure here will do.
let m: Box<AsmCoreMachine> = unsafe {
let machine_size = std::mem::size_of::<AsmCoreMachine>();

let layout = Layout::array::<u8>(machine_size).unwrap();
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
Box::from_raw(raw_allocation)
};
let m_address = &*m as *const AsmCoreMachine as usize;
println!(
"#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_REGISTERS {}",
Expand Down
16 changes: 13 additions & 3 deletions examples/check_real_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::process::{id, Command};
use ckb_vm::{
machine::{
asm::{AsmCoreMachine, AsmMachine},
DefaultMachineBuilder, VERSION0,
DefaultMachineBuilder, DefaultMachineRunner, SupportMachine, VERSION0,
},
ISA_IMC,
};
Expand Down Expand Up @@ -168,7 +168,12 @@ fn check_asm(memory_size: usize) -> Result<(), ()> {
);
println!("Base memory: {}", get_current_memory());
for _ in 0..G_CHECK_LOOP {
let asm_core = AsmCoreMachine::new_with_memory(ISA_IMC, VERSION0, u64::MAX, memory_size);
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new_with_memory(
ISA_IMC,
VERSION0,
u64::MAX,
memory_size,
);
let core = DefaultMachineBuilder::new(asm_core).build();
let mut machine = AsmMachine::new(core);
machine
Expand All @@ -192,7 +197,12 @@ fn check_asm_in_thread(memory_size: usize) -> Result<(), ()> {
);
println!("Base memory: {}", get_current_memory());
for _ in 0..G_CHECK_LOOP {
let asm_core = AsmCoreMachine::new_with_memory(ISA_IMC, VERSION0, u64::MAX, memory_size);
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new_with_memory(
ISA_IMC,
VERSION0,
u64::MAX,
memory_size,
);
let core = DefaultMachineBuilder::new(asm_core).build();
let mut machine = AsmMachine::new(core);
machine
Expand Down
4 changes: 3 additions & 1 deletion examples/ckb-vm-runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ impl<Mac: SupportMachine> Syscalls<Mac> for DebugSyscall {

#[cfg(has_asm)]
fn main_asm(code: Bytes, args: Vec<Bytes>) -> Result<(), Box<dyn std::error::Error>> {
let asm_core = ckb_vm::machine::asm::AsmCoreMachine::new(
use ckb_vm::DefaultMachineRunner;

let asm_core = <Box<ckb_vm::machine::asm::AsmCoreMachine> as SupportMachine>::new(
ckb_vm::ISA_IMC | ckb_vm::ISA_B | ckb_vm::ISA_MOP | ckb_vm::ISA_A,
ckb_vm::machine::VERSION2,
u64::MAX,
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ pub use crate::{
instructions::{Instruction, Register},
machine::{
trace::TraceMachine, CoreMachine, DefaultCoreMachine, DefaultMachine,
DefaultMachineBuilder, FlattenedArgsReader, InstructionCycleFunc, Machine, SupportMachine,
DefaultMachineBuilder, DefaultMachineRunner, FlattenedArgsReader, InstructionCycleFunc,
Machine, SupportMachine,
},
memory::{flat::FlatMemory, sparse::SparseMemory, wxorx::WXorXMemory, Memory},
syscalls::Syscalls,
Expand Down
113 changes: 88 additions & 25 deletions src/machine/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use ckb_vm_definitions::{
RET_SLOWPATH, TRACE_ITEM_LENGTH, TRACE_SIZE,
},
instructions::OP_CUSTOM_TRACE_END,
ISA_MOP, MEMORY_FRAMES, MEMORY_FRAME_PAGE_SHIFTS, RISCV_GENERAL_REGISTER_NUMBER,
RISCV_PAGE_SHIFTS,
ISA_MOP, MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_PAGE_SHIFTS,
RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGE_SHIFTS,
};
use rand::{prelude::RngCore, SeedableRng};
use std::alloc::{alloc, Layout};
use std::os::raw::c_uchar;

use crate::{
Expand All @@ -26,8 +27,8 @@ use crate::{
fill_page_data, get_page_indices, memset, round_page_down, round_page_up, FLAG_DIRTY,
FLAG_EXECUTABLE, FLAG_FREEZED, FLAG_WRITABLE, FLAG_WXORX_BIT,
},
CoreMachine, DefaultMachine, Error, Machine, Memory, SupportMachine, MEMORY_FRAME_SHIFTS,
RISCV_PAGES, RISCV_PAGESIZE,
CoreMachine, DefaultMachine, DefaultMachineRunner, Error, Machine, Memory, SupportMachine,
MEMORY_FRAME_SHIFTS, RISCV_PAGES, RISCV_PAGESIZE,
};

impl CoreMachine for Box<AsmCoreMachine> {
Expand Down Expand Up @@ -412,6 +413,56 @@ impl Memory for Box<AsmCoreMachine> {
}

impl SupportMachine for Box<AsmCoreMachine> {
fn new_with_memory(
isa: u8,
version: u32,
max_cycles: u64,
memory_size: usize,
) -> Box<AsmCoreMachine> {
assert_ne!(memory_size, 0);
assert_eq!(memory_size % RISCV_PAGESIZE, 0);
assert_eq!(memory_size % (1 << MEMORY_FRAME_SHIFTS), 0);

let mut machine = unsafe {
let machine_size =
std::mem::size_of::<AsmCoreMachine>() - RISCV_MAX_MEMORY + memory_size;

let layout = Layout::array::<u8>(machine_size).unwrap();
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
Box::from_raw(raw_allocation)
};
machine.registers = [0; RISCV_GENERAL_REGISTER_NUMBER];
machine.pc = 0;
machine.next_pc = 0;
machine.running = 0;
machine.cycles = 0;
machine.max_cycles = max_cycles;
if cfg!(feature = "enable-chaos-mode-by-default") {
machine.chaos_mode = 1;
} else {
machine.chaos_mode = 0;
}
machine.chaos_seed = 0;
machine.load_reservation_address = u64::MAX;
machine.reset_signal = 0;
machine.version = version;
machine.isa = isa;
machine.flags = [0; RISCV_PAGES];
for i in 0..TRACE_SIZE {
machine.traces[i] = Trace::default();
}
machine.frames = [0; MEMORY_FRAMES];

machine.memory_size = memory_size as u64;
machine.frames_size = (memory_size / MEMORY_FRAMESIZE) as u64;
machine.flags_size = (memory_size / RISCV_PAGESIZE) as u64;

machine.last_read_frame = u64::MAX;
machine.last_write_page = u64::MAX;

machine
}

fn cycles(&self) -> u64 {
self.cycles
}
Expand Down Expand Up @@ -473,34 +524,22 @@ pub struct AsmMachine {
pub machine: DefaultMachine<Box<AsmCoreMachine>>,
}

impl AsmMachine {
pub fn new(machine: DefaultMachine<Box<AsmCoreMachine>>) -> Self {
Self { machine }
}
impl DefaultMachineRunner for AsmMachine {
type Inner = Box<AsmCoreMachine>;

pub fn set_max_cycles(&mut self, cycles: u64) {
self.machine.inner.max_cycles = cycles;
fn new(machine: DefaultMachine<Box<AsmCoreMachine>>) -> Self {
Self { machine }
}

pub fn load_program(
&mut self,
program: &Bytes,
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
) -> Result<u64, Error> {
self.machine.load_program(program, args)
fn machine(&self) -> &DefaultMachine<Box<AsmCoreMachine>> {
&self.machine
}

pub fn load_program_with_metadata(
&mut self,
program: &Bytes,
metadata: &ProgramMetadata,
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
) -> Result<u64, Error> {
self.machine
.load_program_with_metadata(program, metadata, args)
fn machine_mut(&mut self) -> &mut DefaultMachine<Box<AsmCoreMachine>> {
&mut self.machine
}

pub fn run(&mut self) -> Result<i8, Error> {
fn run(&mut self) -> Result<i8, Error> {
if self.machine.isa() & ISA_MOP != 0 && self.machine.version() == VERSION0 {
return Err(Error::InvalidVersion);
}
Expand Down Expand Up @@ -573,6 +612,30 @@ impl AsmMachine {
}
Ok(self.machine.exit_code())
}
}

impl AsmMachine {
pub fn set_max_cycles(&mut self, cycles: u64) {
self.machine.inner.max_cycles = cycles;
}

pub fn load_program(
&mut self,
program: &Bytes,
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
) -> Result<u64, Error> {
self.machine.load_program(program, args)
}

pub fn load_program_with_metadata(
&mut self,
program: &Bytes,
metadata: &ProgramMetadata,
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
) -> Result<u64, Error> {
self.machine
.load_program_with_metadata(program, metadata, args)
}

pub fn step(&mut self, decoder: &mut Decoder) -> Result<(), Error> {
// Decode only one instruction into a trace
Expand Down
Loading