-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: unify returns, implement suspend/resume for CALL/CREATE
- Loading branch information
Showing
18 changed files
with
1,010 additions
and
603 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[package] | ||
name = "revm-jit-benches" | ||
description = "revm-jit benchmarks" | ||
homepage = "https://github.com/danipopes/revm-jit/tree/main/benches/" | ||
publish = false | ||
|
||
version.workspace = true | ||
authors.workspace = true | ||
edition.workspace = true | ||
rust-version.workspace = true | ||
license.workspace = true | ||
categories.workspace = true | ||
keywords.workspace = true | ||
repository.workspace = true | ||
exclude.workspace = true | ||
|
||
[dependencies] | ||
revm-jit.workspace = true | ||
|
||
revm-interpreter.workspace = true | ||
revm-primitives.workspace = true | ||
|
||
clap = { version = "4", features = ["derive"] } | ||
color-eyre.workspace = true | ||
tracing-error.workspace = true | ||
tracing-subscriber = { workspace = true, features = ["fmt", "env-filter"] } | ||
|
||
[dev-dependencies] | ||
criterion = "0.5" | ||
|
||
[features] | ||
default = ["llvm"] | ||
llvm = ["revm-jit/llvm"] | ||
cranelift = ["revm-jit/cranelift"] | ||
|
||
[[bin]] | ||
name = "revm-jit-benches" | ||
path = "src/main.rs" | ||
required-features = ["llvm"] | ||
doc = false | ||
|
||
[[bench]] | ||
name = "bench" | ||
path = "benches/bench.rs" | ||
required-features = ["llvm"] | ||
harness = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
use criterion::{ | ||
criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, | ||
}; | ||
use revm_interpreter::EMPTY_SHARED_MEMORY; | ||
use revm_jit::{llvm, EvmContext, EvmStack, JitEvm, JitEvmFn}; | ||
use revm_jit_benches::Bench; | ||
use revm_primitives::{Env, SpecId}; | ||
use std::time::Duration; | ||
|
||
const SPEC_ID: SpecId = SpecId::CANCUN; | ||
|
||
fn bench(c: &mut Criterion) { | ||
for bench in &revm_jit_benches::get_benches() { | ||
if matches!(bench.name, "push0_proxy" | "weth") { | ||
continue; | ||
} | ||
run_bench(c, bench); | ||
} | ||
} | ||
|
||
fn run_bench(c: &mut Criterion, bench: &Bench) { | ||
let Bench { name, bytecode, calldata, stack_input, native } = bench; | ||
|
||
let mut g = mk_group(c, name); | ||
|
||
let mut env = Env::default(); | ||
env.tx.data = calldata.clone().into(); | ||
|
||
let bytecode = revm_interpreter::analysis::to_analysed(revm_primitives::Bytecode::new_raw( | ||
revm_primitives::Bytes::copy_from_slice(bytecode), | ||
)); | ||
let bytecode_hash = bytecode.hash_slow(); | ||
let contract = revm_interpreter::Contract::new_env(&env, bytecode, bytecode_hash); | ||
let mut host = revm_interpreter::DummyHost::new(env); | ||
|
||
let gas_limit = 100_000; | ||
let bytecode = contract.bytecode.original_bytecode_slice(); | ||
|
||
let table = &revm_interpreter::opcode::make_instruction_table::< | ||
revm_interpreter::DummyHost, | ||
revm_primitives::CancunSpec, | ||
>(); | ||
|
||
// Set up JIT. | ||
let opt_level = revm_jit::OptimizationLevel::Aggressive; | ||
let context = llvm::inkwell::context::Context::create(); | ||
let backend = llvm::JitEvmLlvmBackend::new(&context, opt_level).unwrap(); | ||
let mut jit = JitEvm::new(backend); | ||
if !stack_input.is_empty() { | ||
jit.set_inspect_stack_length(true); | ||
} | ||
jit.set_disable_gas(true); | ||
|
||
if let Some(native) = *native { | ||
g.bench_function("native", |b| b.iter(native)); | ||
} | ||
|
||
let mut stack = EvmStack::new(); | ||
let mut call_jit = |f: JitEvmFn| { | ||
for (i, input) in stack_input.iter().enumerate() { | ||
stack.as_mut_slice()[i] = input.into(); | ||
} | ||
let mut stack_len = stack_input.len(); | ||
|
||
let mut interpreter = | ||
revm_interpreter::Interpreter::new(contract.clone(), gas_limit, false); | ||
host.clear(); | ||
let mut ecx = EvmContext::from_interpreter(&mut interpreter, &mut host); | ||
|
||
unsafe { f.call(Some(&mut stack), Some(&mut stack_len), &mut ecx) } | ||
}; | ||
|
||
let jit_no_gas = jit.compile(Some(name), bytecode, SPEC_ID).unwrap(); | ||
g.bench_function("revm-jit/no_gas", |b| b.iter(|| call_jit(jit_no_gas))); | ||
|
||
unsafe { jit.free_all_functions() }.unwrap(); | ||
jit.set_disable_gas(false); | ||
let jit_gas = jit.compile(Some(name), bytecode, SPEC_ID).unwrap(); | ||
g.bench_function("revm-jit/gas", |b| b.iter(|| call_jit(jit_gas))); | ||
|
||
g.bench_function("revm-interpreter", |b| { | ||
b.iter(|| { | ||
let mut int = revm_interpreter::Interpreter::new(contract.clone(), gas_limit, false); | ||
let mut host = host.clone(); | ||
|
||
int.stack.data_mut().extend_from_slice(stack_input); | ||
|
||
int.run(EMPTY_SHARED_MEMORY, table, &mut host) | ||
}) | ||
}); | ||
|
||
g.finish(); | ||
} | ||
|
||
fn mk_group<'a>(c: &'a mut Criterion, name: &str) -> BenchmarkGroup<'a, WallTime> { | ||
let mut g = c.benchmark_group(name); | ||
g.sample_size(100); | ||
g.warm_up_time(Duration::from_secs(5)); | ||
g.measurement_time(Duration::from_secs(10)); | ||
g | ||
} | ||
|
||
criterion_group!(benches, bench); | ||
criterion_main!(benches); |
Oops, something went wrong.