Skip to content

Commit

Permalink
Optimized the stack allocations of create and call opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
valo committed Jun 19, 2023
1 parent b51827d commit a661180
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 57 deletions.
11 changes: 8 additions & 3 deletions bins/revme/src/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,14 @@ pub fn run(
let console_bar = console_bar.clone();
let elapsed = elapsed.clone();

joins.push(
std::thread::Builder::new()
.stack_size(50 * 1024 * 1024)
let mut thread = std::thread::Builder::new();

// Allow bigger stack in debug mode to prevent stack overflow errors
if cfg!(debug_assertions) {
thread = thread.stack_size(3 * 1024 * 1024);
}

joins.push(thread
.spawn(move || loop {
let (index, test_path) = {
let mut queue = queue.lock().unwrap();
Expand Down
31 changes: 26 additions & 5 deletions crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ pub fn selfdestruct<SPEC: Spec>(interpreter: &mut Interpreter, host: &mut dyn Ho
interpreter.instruction_result = InstructionResult::SelfDestruct;
}

pub fn create<const IS_CREATE2: bool, SPEC: Spec>(
pub fn prepare_create_inputs<const IS_CREATE2: bool, SPEC: Spec>(
interpreter: &mut Interpreter,
host: &mut dyn Host,
create_inputs: &mut Option<Box<CreateInputs>>
) {
check_staticcall!(interpreter);
if IS_CREATE2 {
Expand Down Expand Up @@ -282,15 +282,18 @@ pub fn create<const IS_CREATE2: bool, SPEC: Spec>(
}
gas!(interpreter, gas_limit);

let mut create_input = CreateInputs {
*create_inputs = Some(Box::new(CreateInputs {
caller: interpreter.contract.address,
scheme,
value,
init_code: code,
gas_limit,
};
}));
}

pub fn handle_create_result(interpreter: &mut Interpreter, result: (InstructionResult, Option<B160>, Gas, Bytes)) {
let (return_reason, address, gas, return_data) = result;

let (return_reason, address, gas, return_data) = host.create(&mut create_input);
interpreter.return_data_buffer = match return_reason {
// Save data to return data buffer if the create reverted
return_revert!() => return_data,
Expand Down Expand Up @@ -321,6 +324,24 @@ pub fn create<const IS_CREATE2: bool, SPEC: Spec>(
}
}

pub fn create<const IS_CREATE2: bool, SPEC: Spec>(
interpreter: &mut Interpreter,
host: &mut dyn Host,
) {
let mut create_input: Option<Box<CreateInputs>> = None;
prepare_create_inputs::<IS_CREATE2, SPEC>(interpreter, &mut create_input);

if create_input.is_none() {
return;
}

let mut create_input = create_input.unwrap();

let ret = host.create(&mut create_input);

handle_create_result(interpreter, ret);
}

pub fn call<SPEC: Spec>(interpreter: &mut Interpreter, host: &mut dyn Host) {
call_inner::<SPEC>(interpreter, CallScheme::Call, host);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/interpreter/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub struct Interpreter {
/// Is interpreter call static.
pub is_static: bool,
/// Contract information and invoking data
pub contract: Contract,
pub contract: Box<Contract>,
/// Memory limit. See [`crate::CfgEnv`].
#[cfg(feature = "memory_limit")]
pub memory_limit: u64,
Expand All @@ -55,7 +55,7 @@ impl Interpreter {
}

/// Create new interpreter
pub fn new(contract: Contract, gas_limit: u64, is_static: bool) -> Self {
pub fn new(contract: Box<Contract>, gas_limit: u64, is_static: bool) -> Self {
#[cfg(not(feature = "memory_limit"))]
{
Self {
Expand Down
8 changes: 4 additions & 4 deletions crates/interpreter/src/interpreter/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub struct Contract {
}

impl Contract {
pub fn new(input: Bytes, bytecode: Bytecode, address: B160, caller: B160, value: U256) -> Self {
let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed");
pub fn new(input: Bytes, bytecode: &Bytecode, address: B160, caller: B160, value: U256) -> Self {
let bytecode = to_analysed(bytecode.clone()).try_into().expect("it is analyzed");

Self {
input,
Expand All @@ -39,7 +39,7 @@ impl Contract {
};
Self::new(
env.tx.data.clone(),
bytecode,
&bytecode,
contract_address,
env.tx.caller,
env.tx.value,
Expand All @@ -50,7 +50,7 @@ impl Contract {
self.bytecode.jump_map().is_valid(possition)
}

pub fn new_with_context(input: Bytes, bytecode: Bytecode, call_context: &CallContext) -> Self {
pub fn new_with_context(input: Bytes, bytecode: &Bytecode, call_context: &CallContext) -> Self {
Self::new(
input,
bytecode,
Expand Down
Loading

0 comments on commit a661180

Please sign in to comment.