core/vm: reuse stack arena

This commit is contained in:
MariusVanDerWijden 2025-05-21 16:39:58 +02:00
parent 8125479ad8
commit 19eb45376a
4 changed files with 22 additions and 3 deletions

View file

@ -93,6 +93,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
} }
// Execute the message to preload the implicit touched states // Execute the message to preload the implicit touched states
evm := vm.NewEVM(NewEVMBlockContext(header, p.chain, nil), stateCpy, p.config, cfg) evm := vm.NewEVM(NewEVMBlockContext(header, p.chain, nil), stateCpy, p.config, cfg)
defer evm.Free()
// Convert the transaction into an executable message and pre-cache its sender // Convert the transaction into an executable message and pre-cache its sender
msg, err := TransactionToMessage(tx, signer, header.BaseFee) msg, err := TransactionToMessage(tx, signer, header.BaseFee)

View file

@ -81,6 +81,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
} }
context = NewEVMBlockContext(header, p.chain, nil) context = NewEVMBlockContext(header, p.chain, nil)
evm := vm.NewEVM(context, tracingStateDB, p.config, cfg) evm := vm.NewEVM(context, tracingStateDB, p.config, cfg)
defer evm.Free()
if beaconRoot := block.BeaconRoot(); beaconRoot != nil { if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
ProcessBeaconBlockRoot(*beaconRoot, evm) ProcessBeaconBlockRoot(*beaconRoot, evm)

View file

@ -170,6 +170,12 @@ func (evm *EVM) Cancel() {
evm.abort.Store(true) evm.abort.Store(true)
} }
// Free returns some memory allocated by the EVM, should be called after the EVM was used
// for the last time. Not necessary, but an improvement.
func (evm *EVM) Free() {
returnStack(evm.arena)
}
// Cancelled returns true if Cancel has been called // Cancelled returns true if Cancel has been called
func (evm *EVM) Cancelled() bool { func (evm *EVM) Cancelled() bool {
return evm.abort.Load() return evm.abort.Load()

View file

@ -18,6 +18,7 @@ package vm
import ( import (
"slices" "slices"
"sync"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -29,9 +30,19 @@ type stackArena struct {
} }
func newArena() *stackArena { func newArena() *stackArena {
return &stackArena{ return stackPool.New().(*stackArena)
data: make([]uint256.Int, 1025), }
}
var stackPool = sync.Pool{
New: func() any {
return &stackArena{
data: make([]uint256.Int, 1025),
}
},
}
func returnStack(arena *stackArena) {
stackPool.Put(arena)
} }
// stack returns an instance of a stack which uses the underlying arena. The instance // stack returns an instance of a stack which uses the underlying arena. The instance