Skip to content

core/vm: Idea for enabling an experimental evm#34645

Draft
kevaundray wants to merge 6 commits intoethereum:masterfrom
kevaundray:kw/interp-fast
Draft

core/vm: Idea for enabling an experimental evm#34645
kevaundray wants to merge 6 commits intoethereum:masterfrom
kevaundray:kw/interp-fast

Conversation

@kevaundray
Copy link
Copy Markdown
Contributor

Opening this PR to get @fjl thoughts and to spur some ideas on pathways to optimizing the EVM in geth.

This is a simple idea for enabling an experimental EVM that can be developed/optimized alongside the normal EVM.

Currently it only optimizes, commonly used compute opcodes using a switch dispatch (the savings are about 50%), and then fallsback to the normal interpreter for everything else. None of the optimization techniques here are new.

Comment on lines -201 to -224
// All ops with a dynamic memory usage also has a dynamic gas cost.
var operation *operation
var memorySize uint64
if operation.dynamicGas != nil {
// calculate the new memory size and expand the memory to fit
// the operation
// Memory check needs to be done prior to evaluating the dynamic gas portion,
// to detect calculation overflows
if operation.memorySize != nil {
memSize, overflow := operation.memorySize(stack)
if overflow {
return nil, ErrGasUintOverflow
}
// memory is expanded in words of 32 bytes. Gas
// is also calculated in words.
if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow {
return nil, ErrGasUintOverflow
}
}
// Consume the gas and return an error if not enough gas is available.
// cost is explicitly set so that the capture state defer method can get the proper cost
var dynamicCost uint64
dynamicCost, err = operation.dynamicGas(evm, contract, stack, mem, memorySize)
cost += dynamicCost // for tracing
if err != nil {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the biggest diff on existing code. This functionality is used in the experimental EVM so I pulled it out into chargeGasOp function to avoid code duplication

Comment on lines +49 to +50
// - all inlined opcodes only touch the stack, so executing a few extra ops
// before detecting OOG has no observable side effects.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This optimization in spirit, just says; we will execute and group "basic blocks" wrt their gas cost

contract.Gas -= gasUsed
return nil, &ErrStackUnderflow{stackLen: stack.len(), required: 2}
}
x, y := stack.pop(), stack.peek()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Its possible to remove these methods, and use the raw stack slice. It saves about 7-8.5% but makes the code harder to read

continue // skip pc++
}
// Flush gas and fall back to normal dispatch
default:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Here we just fall back to the normal interpreter for everything else

@kevaundray kevaundray changed the title core/evm: Idea for enabling an experimental evm core/vm: Idea for enabling an experimental evm Apr 3, 2026
x, y := stack.pop(), stack.peek()
y.Sub(&x, y)

case MUL:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sidenote: A different way to have done this, would have been to use go generate

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.

1 participant