Skip to content

Commit

Permalink
perf: reduce dynamic dispatch for inspectors (#9011)
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr authored Oct 3, 2024
1 parent ecf37f2 commit df2e91b
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
4 changes: 2 additions & 2 deletions crates/evm/core/src/backend/cow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ impl<'a> CowBackend<'a> {
/// Note: in case there are any cheatcodes executed that modify the environment, this will
/// update the given `env` with the new values.
#[instrument(name = "inspect", level = "debug", skip_all)]
pub fn inspect(
pub fn inspect<I: InspectorExt>(
&mut self,
env: &mut EnvWithHandlerCfg,
inspector: &mut dyn InspectorExt,
inspector: &mut I,
) -> eyre::Result<ResultAndState> {
// this is a new call to inspect with a new env, so even if we've cloned the backend
// already, we reset the initialized state
Expand Down
4 changes: 2 additions & 2 deletions crates/evm/core/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,10 +751,10 @@ impl Backend {
/// Note: in case there are any cheatcodes executed that modify the environment, this will
/// update the given `env` with the new values.
#[instrument(name = "inspect", level = "debug", skip_all)]
pub fn inspect(
pub fn inspect<I: InspectorExt>(
&mut self,
env: &mut EnvWithHandlerCfg,
inspector: &mut dyn InspectorExt,
inspector: &mut I,
) -> eyre::Result<ResultAndState> {
self.initialize(env);
let mut evm = crate::utils::new_evm_with_inspector(self, env.clone(), inspector);
Expand Down
6 changes: 3 additions & 3 deletions crates/evm/core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ pub fn alphanet_handler_register<EXT, DB: revm::Database>(handler: &mut EvmHandl
}

/// Creates a new EVM with the given inspector.
pub fn new_evm_with_inspector<'evm, 'i, 'db>(
pub fn new_evm_with_inspector<'evm, 'i, 'db, I: InspectorExt + ?Sized>(
db: &'db mut dyn DatabaseExt,
env: revm::primitives::EnvWithHandlerCfg,
inspector: &'i mut dyn InspectorExt,
) -> revm::Evm<'evm, &'i mut dyn InspectorExt, &'db mut dyn DatabaseExt> {
inspector: &'i mut I,
) -> revm::Evm<'evm, &'i mut I, &'db mut dyn DatabaseExt> {
let revm::primitives::EnvWithHandlerCfg { env, handler_cfg } = env;

// NOTE: We could use `revm::Evm::builder()` here, but on the current patch it has some
Expand Down
25 changes: 22 additions & 3 deletions crates/evm/evm/src/inspectors/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,14 +543,14 @@ impl<'a> InspectorStackRefMut<'a> {
self.in_inner_context = true;

let env = EnvWithHandlerCfg::new_with_spec_id(ecx.env.clone(), ecx.spec_id());
let res = {
let mut evm = crate::utils::new_evm_with_inspector(&mut ecx.db, env, self);
let res = self.with_stack(|inspector| {
let mut evm = crate::utils::new_evm_with_inspector(&mut ecx.db, env, inspector);
let res = evm.transact();

// need to reset the env in case it was modified via cheatcodes during execution
ecx.env = evm.context.evm.inner.env;
res
};
});

self.in_inner_context = false;
self.inner_context_data = None;
Expand Down Expand Up @@ -621,6 +621,25 @@ impl<'a> InspectorStackRefMut<'a> {
};
(InterpreterResult { result, output, gas }, address)
}

/// Moves out of references, constructs an [`InspectorStack`] and runs the given closure with
/// it.
fn with_stack<O>(&mut self, f: impl FnOnce(&mut InspectorStack) -> O) -> O {
let mut stack = InspectorStack {
cheatcodes: self.cheatcodes.as_deref_mut().map(std::mem::take),
inner: std::mem::take(self.inner),
};

let out = f(&mut stack);

if let Some(cheats) = self.cheatcodes.as_deref_mut() {
*cheats = stack.cheatcodes.take().unwrap();
}

*self.inner = stack.inner;

out
}
}

impl<'a> Inspector<&mut dyn DatabaseExt> for InspectorStackRefMut<'a> {
Expand Down

0 comments on commit df2e91b

Please sign in to comment.