Skip to content

Commit b9855fe

Browse files
committed
use block-wide allocation
1 parent e24f1f8 commit b9855fe

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

crates/vm/backends/levm/mod.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use ethrex_common::{
1818
},
1919
};
2020
use ethrex_levm::EVMConfig;
21+
use ethrex_levm::call_frame::Stack;
2122
use ethrex_levm::constants::{SYS_CALL_GAS_LIMIT, TX_BASE_COST};
2223
use ethrex_levm::db::gen_db::GeneralizedDatabase;
2324
use ethrex_levm::errors::{InternalError, TxValidationError};
@@ -91,18 +92,24 @@ impl LEVM {
9192
) -> Result<BlockExecutionResult, EvmError> {
9293
Self::prepare_block(block, db, vm_type)?;
9394

95+
let mut shared_stack_pool = Vec::with_capacity(1024);
96+
for _ in 0..1024 {
97+
shared_stack_pool.push(Stack::default())
98+
}
99+
94100
let mut receipts = Vec::new();
95101
let mut cumulative_gas_used = 0;
96102

97103
for (tx, tx_sender) in block.body.get_transactions_with_sender().map_err(|error| {
98104
EvmError::Transaction(format!("Couldn't recover addresses with error: {error}"))
99105
})? {
100-
let report = Self::execute_tx(
106+
let report = Self::execute_tx_in_block(
101107
tx,
102108
tx_sender,
103109
&block.header,
104110
db,
105-
vm_type
111+
vm_type,
112+
&mut shared_stack_pool,
106113
)?;
107114
LEVM::send_state_transitions_tx(&merkleizer, db, queue_length)?;
108115

@@ -221,6 +228,26 @@ impl LEVM {
221228
vm.execute().map_err(VMError::into)
222229
}
223230

231+
pub fn execute_tx_in_block(
232+
// The transaction to execute.
233+
tx: &Transaction,
234+
// The transactions recovered address
235+
tx_sender: Address,
236+
// The block header for the current block.
237+
block_header: &BlockHeader,
238+
db: &mut GeneralizedDatabase,
239+
vm_type: VMType,
240+
stack_pool: &mut Vec<Stack>,
241+
) -> Result<ExecutionReport, EvmError> {
242+
let env = Self::setup_env(tx, tx_sender, block_header, db, vm_type)?;
243+
let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?;
244+
245+
std::mem::swap(&mut vm.stack, stack_pool);
246+
let result = vm.execute().map_err(VMError::into);
247+
std::mem::swap(&mut vm.stack, stack_pool);
248+
result
249+
}
250+
224251
pub fn undo_last_tx(db: &mut GeneralizedDatabase) -> Result<(), EvmError> {
225252
db.undo_last_transaction()?;
226253
Ok(())

crates/vm/levm/src/vm.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ pub struct VM<'a> {
309309
/// The current call frame.
310310
pub current_call_frame: CallFrame,
311311
/// Stack allocations, call_frame.depth points to the index
312-
pub stack: Box<[Stack; 1025]>,
312+
pub stack: Vec<Stack>,
313313
pub env: Environment,
314314
pub substate: Substate,
315315
pub db: &'a mut GeneralizedDatabase,
@@ -344,13 +344,6 @@ impl<'a> VM<'a> {
344344

345345
let fork = env.config.fork;
346346

347-
let mut stack = Box::new_uninit_slice(1025);
348-
for i in 0..1025 {
349-
stack[i].write(Stack::default());
350-
}
351-
#[expect(unsafe_code)]
352-
let stack = unsafe { stack.assume_init().try_into().unwrap() };
353-
354347
let mut vm = Self {
355348
call_frames: Vec::new(),
356349
substate,
@@ -378,7 +371,7 @@ impl<'a> VM<'a> {
378371
0,
379372
Memory::default(),
380373
),
381-
stack,
374+
stack: Vec::new(),
382375
env,
383376
opcode_table: VM::build_opcode_table(fork),
384377
};
@@ -412,6 +405,9 @@ impl<'a> VM<'a> {
412405

413406
/// Executes a whole external transaction. Performing validations at the beginning.
414407
pub fn execute(&mut self) -> Result<ExecutionReport, VMError> {
408+
while self.stack.len() < 1024 {
409+
self.stack.push(Stack::default());
410+
}
415411
if let Err(e) = self.prepare_execution() {
416412
// Restore cache to state previous to this Tx execution because this Tx is invalid.
417413
self.restore_cache_state()?;

0 commit comments

Comments
 (0)