Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
perf: reintroduce resize_memory fn
Reintroduce #1361.
  • Loading branch information
DaniPopes committed Jul 22, 2025
commit b4f6a94a9b17866fa9516b1dc2ca5be6aade6879
3 changes: 2 additions & 1 deletion crates/interpreter/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,17 @@ pub struct MemoryGas {

impl MemoryGas {
/// Creates a new `MemoryGas` instance with zero memory allocation.
#[inline]
pub const fn new() -> Self {
Self {
words_num: 0,
expansion_cost: 0,
}
}

#[inline]
/// Records a new memory length and calculates additional cost if memory is expanded.
/// Returns the additional gas cost required, or None if no expansion is needed.
#[inline]
pub fn record_new_len(&mut self, new_num: usize) -> Option<u64> {
if new_num <= self.words_num {
return None;
Expand Down
20 changes: 9 additions & 11 deletions crates/interpreter/src/instructions/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,15 @@ macro_rules! resize_memory {
$crate::resize_memory!($interpreter, $offset, $len, ())
};
($interpreter:expr, $offset:expr, $len:expr, $ret:expr) => {
let words_num = $crate::interpreter::num_words($offset.saturating_add($len));
match $interpreter.gas.record_memory_expansion(words_num) {
$crate::gas::MemoryExtensionResult::Extended => {
$interpreter.memory.resize(words_num * 32);
}
$crate::gas::MemoryExtensionResult::OutOfGas => {
$interpreter.halt($crate::InstructionResult::MemoryOOG);
return $ret;
}
$crate::gas::MemoryExtensionResult::Same => (), // no action
};
if !$crate::interpreter::resize_memory(
&mut $interpreter.gas,
&mut $interpreter.memory,
$offset,
$len,
) {
$interpreter.halt($crate::InstructionResult::MemoryOOG);
return $ret;
}
};
}

Expand Down
9 changes: 8 additions & 1 deletion crates/interpreter/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use ext_bytecode::ExtBytecode;
pub use input::InputsImpl;
pub use return_data::ReturnDataImpl;
pub use runtime_flags::RuntimeFlags;
pub use shared_memory::{num_words, SharedMemory};
pub use shared_memory::{num_words, resize_memory, SharedMemory};
pub use stack::{Stack, STACK_LIMIT};

// imports
Expand Down Expand Up @@ -183,6 +183,13 @@ impl<EXT> InterpreterTypes for EthInterpreter<EXT> {
}

impl<IW: InterpreterTypes> Interpreter<IW> {
/// Performs EVM memory resize.
#[inline]
#[must_use]
pub fn resize_memory(&mut self, offset: usize, len: usize) -> bool {
resize_memory(&mut self.gas, &mut self.memory, offset, len)
}

/// Takes the next action from the control and returns it.
#[inline]
pub fn take_next_action(&mut self) -> InterpreterAction {
Expand Down
36 changes: 36 additions & 0 deletions crates/interpreter/src/interpreter/shared_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,42 @@ pub const fn num_words(len: usize) -> usize {
len.saturating_add(31) / 32
}

/// Performs EVM memory resize.
#[inline]
#[must_use]
pub fn resize_memory<Memory: MemoryTr>(
gas: &mut crate::Gas,
memory: &mut Memory,
offset: usize,
len: usize,
) -> bool {
let new_num_words = num_words(offset.saturating_add(len));
if new_num_words > gas.memory().words_num {
resize_memory_cold(gas, memory, new_num_words)
} else {
true
}
}

#[cold]
#[inline(never)]
fn resize_memory_cold<Memory: MemoryTr>(
gas: &mut crate::Gas,
memory: &mut Memory,
new_num_words: usize,
) -> bool {
let cost = unsafe {
gas.memory_mut()
.record_new_len(new_num_words)
.unwrap_unchecked()
};
if !gas.record_cost(cost) {
return false;
}
memory.resize(new_num_words * 32);
true
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading