From 3b28836f18b7f821b427a8667ab95412062767b7 Mon Sep 17 00:00:00 2001 From: Valentin Mihov Date: Mon, 11 Sep 2023 12:33:10 +0300 Subject: [PATCH] Never inline the prepare functions These functions are used for keeping the stack memory clean on the host recursive code paths. EVM supports up to 1024 levels of recursion, so if one is not careful with the stack memory allocations, the stack memory can blow up. Benchmarks show dramatic stack memory improvements when ont inlining these functions. A recursive bomb uses around 1.1MB of stack when these functions are not inlined. If inlined the recursive bombs blow up the stack. --- bins/revme/src/statetest/runner.rs | 7 +------ crates/interpreter/src/instructions/host.rs | 2 ++ crates/revm/src/evm_impl.rs | 2 ++ 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bins/revme/src/statetest/runner.rs b/bins/revme/src/statetest/runner.rs index bee54a837c..af90d49bed 100644 --- a/bins/revme/src/statetest/runner.rs +++ b/bins/revme/src/statetest/runner.rs @@ -365,12 +365,7 @@ pub fn run( let console_bar = console_bar.clone(); let elapsed = elapsed.clone(); - 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(4 * 1024 * 1024); - //} + let thread: std::thread::Builder = std::thread::Builder::new(); joins.push( thread diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 95d549d633..5fbfa20253 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -239,6 +239,7 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut dyn Ho interpreter.instruction_result = InstructionResult::SelfDestruct; } +#[inline(never)] pub fn prepare_create_inputs( interpreter: &mut Interpreter, host: &mut dyn Host, @@ -368,6 +369,7 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mut dyn Hos call_inner::(interpreter, CallScheme::StaticCall, host); } +#[inline(never)] fn prepare_call_inputs( interpreter: &mut Interpreter, scheme: CallScheme, diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index da83fd3b89..77efd1f00b 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -340,6 +340,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, (new_state, logs, gas_used, gas_refunded) } + #[inline(never)] fn prepare_create(&mut self, inputs: &CreateInputs) -> Result { let gas = Gas::new(inputs.gas_limit); @@ -629,6 +630,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, } } + #[inline(never)] fn prepare_call(&mut self, inputs: &CallInputs) -> Result { let gas = Gas::new(inputs.gas_limit); let account = match self