Skip to content

Comments

core: use an arena allocator in the STF#33862

Open
tellabg wants to merge 2 commits intoethereum:masterfrom
tellabg:arena-allocator
Open

core: use an arena allocator in the STF#33862
tellabg wants to merge 2 commits intoethereum:masterfrom
tellabg:arena-allocator

Conversation

@tellabg
Copy link

@tellabg tellabg commented Feb 17, 2026

This is part of the work needed to speed up the execution of keeper as a guest program client, but I think it will also improve the performance of regualr geth. The idea is well-known to zig developer: pre-allocate a buffer, make all your allocations from it and release (or reuse) the whole buffer when processing a new block.

This is particularly well suited to the STF since all allocations are meant to last as long as the transition function is being executed. Afterwards, the data is released. The data that needs to survive the STF is copied at the end.

This PR ntroduces an allocator type that can be used to allocate memory. By default, it's just a proxy for make but in a zkvm context it will be a bump allocator. We could also use the bump allocator during normal sync operations, which should make block processing faster.

The outstanding problem is that some structures use pointers, and this is not playing nice with the golang GC, as these will escape to heap. So some further modifications need to occur, which I am currently testing.

Note that this makes a lot of "pre-allocate" AI slop PRs moot and that once this is included, we can close a ton of them.

core/evm.go Outdated
Comment on lines 99 to 105
var gasPrice *uint256.Int
if gasPrice != nil {
gasPrice := arena.New[uint256.Int](alloc)
if gasPrice.Set(msg.GasPrice) {
panic("overflow")
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is meant to be functionally equivalent to MustFromBig but it should be in its own function.

random = &header.MixDigest
}
blockNumber := new(big.Int).Set(header.Number)
difficulty := new(big.Int).Set(header.Difficulty)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this change

Multi-slab BumpAllocator (8 MiB per slab, 1 GiB cap) with per-block
usage logging (used, peak, slab count, total capacity).

Fix GC corruption: only flat types (uint256.Int) are safe in the
[]byte arena slab. Pointer-containing types (Contract, Memory,
stateTransition, ExecutionResult) use standard heap allocation.

Convert Message fields from *big.Int to uint256.Int value types,
allowing Message and Stack to remain arena-allocated without GC
issues. The buyGas() function still uses big.Int internally for
balance overflow detection.

Arena hardening: clear() for optimized zeroing, Stack pre-alloc
1024 capacity, prefetcher isolation (Allocator=nil).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants