core/vm: use pointer to avoid unnecessary copy in validate function

This commit is contained in:
tony 2024-01-22 21:13:24 +08:00
parent f55a10b64d
commit 4576138753
4 changed files with 41 additions and 41 deletions

View file

@ -57,29 +57,29 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
var table *JumpTable var table *JumpTable
switch { switch {
case evm.chainRules.IsCancun: case evm.chainRules.IsCancun:
table = &cancunInstructionSet table = cancunInstructionSet
case evm.chainRules.IsShanghai: case evm.chainRules.IsShanghai:
table = &shanghaiInstructionSet table = shanghaiInstructionSet
case evm.chainRules.IsMerge: case evm.chainRules.IsMerge:
table = &mergeInstructionSet table = mergeInstructionSet
case evm.chainRules.IsLondon: case evm.chainRules.IsLondon:
table = &londonInstructionSet table = londonInstructionSet
case evm.chainRules.IsBerlin: case evm.chainRules.IsBerlin:
table = &berlinInstructionSet table = berlinInstructionSet
case evm.chainRules.IsIstanbul: case evm.chainRules.IsIstanbul:
table = &istanbulInstructionSet table = istanbulInstructionSet
case evm.chainRules.IsConstantinople: case evm.chainRules.IsConstantinople:
table = &constantinopleInstructionSet table = constantinopleInstructionSet
case evm.chainRules.IsByzantium: case evm.chainRules.IsByzantium:
table = &byzantiumInstructionSet table = byzantiumInstructionSet
case evm.chainRules.IsEIP158: case evm.chainRules.IsEIP158:
table = &spuriousDragonInstructionSet table = spuriousDragonInstructionSet
case evm.chainRules.IsEIP150: case evm.chainRules.IsEIP150:
table = &tangerineWhistleInstructionSet table = tangerineWhistleInstructionSet
case evm.chainRules.IsHomestead: case evm.chainRules.IsHomestead:
table = &homesteadInstructionSet table = homesteadInstructionSet
default: default:
table = &frontierInstructionSet table = frontierInstructionSet
} }
var extraEips []int var extraEips []int
if len(evm.Config.ExtraEips) > 0 { if len(evm.Config.ExtraEips) > 0 {

View file

@ -62,7 +62,7 @@ var (
// JumpTable contains the EVM opcodes supported at a given fork. // JumpTable contains the EVM opcodes supported at a given fork.
type JumpTable [256]*operation type JumpTable [256]*operation
func validate(jt JumpTable) JumpTable { func validate(jt *JumpTable) *JumpTable {
for i, op := range jt { for i, op := range jt {
if op == nil { if op == nil {
panic(fmt.Sprintf("op %#x is not set", i)) panic(fmt.Sprintf("op %#x is not set", i))
@ -80,25 +80,25 @@ func validate(jt JumpTable) JumpTable {
return jt return jt
} }
func newCancunInstructionSet() JumpTable { func newCancunInstructionSet() *JumpTable {
instructionSet := newShanghaiInstructionSet() instructionSet := newShanghaiInstructionSet()
enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) enable4844(instructionSet) // EIP-4844 (BLOBHASH opcode)
enable7516(&instructionSet) // EIP-7516 (BLOBBASEFEE opcode) enable7516(instructionSet) // EIP-7516 (BLOBBASEFEE opcode)
enable1153(&instructionSet) // EIP-1153 "Transient Storage" enable1153(instructionSet) // EIP-1153 "Transient Storage"
enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) enable5656(instructionSet) // EIP-5656 (MCOPY opcode)
enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction enable6780(instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction
return validate(instructionSet) return validate(instructionSet)
} }
func newShanghaiInstructionSet() JumpTable { func newShanghaiInstructionSet() *JumpTable {
instructionSet := newMergeInstructionSet() instructionSet := newMergeInstructionSet()
enable3855(&instructionSet) // PUSH0 instruction enable3855(instructionSet) // PUSH0 instruction
enable3860(&instructionSet) // Limit and meter initcode enable3860(instructionSet) // Limit and meter initcode
return validate(instructionSet) return validate(instructionSet)
} }
func newMergeInstructionSet() JumpTable { func newMergeInstructionSet() *JumpTable {
instructionSet := newLondonInstructionSet() instructionSet := newLondonInstructionSet()
instructionSet[PREVRANDAO] = &operation{ instructionSet[PREVRANDAO] = &operation{
execute: opRandom, execute: opRandom,
@ -111,36 +111,36 @@ func newMergeInstructionSet() JumpTable {
// newLondonInstructionSet returns the frontier, homestead, byzantium, // newLondonInstructionSet returns the frontier, homestead, byzantium,
// constantinople, istanbul, petersburg, berlin and london instructions. // constantinople, istanbul, petersburg, berlin and london instructions.
func newLondonInstructionSet() JumpTable { func newLondonInstructionSet() *JumpTable {
instructionSet := newBerlinInstructionSet() instructionSet := newBerlinInstructionSet()
enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 enable3529(instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 enable3198(instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
return validate(instructionSet) return validate(instructionSet)
} }
// newBerlinInstructionSet returns the frontier, homestead, byzantium, // newBerlinInstructionSet returns the frontier, homestead, byzantium,
// constantinople, istanbul, petersburg and berlin instructions. // constantinople, istanbul, petersburg and berlin instructions.
func newBerlinInstructionSet() JumpTable { func newBerlinInstructionSet() *JumpTable {
instructionSet := newIstanbulInstructionSet() instructionSet := newIstanbulInstructionSet()
enable2929(&instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929 enable2929(instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929
return validate(instructionSet) return validate(instructionSet)
} }
// newIstanbulInstructionSet returns the frontier, homestead, byzantium, // newIstanbulInstructionSet returns the frontier, homestead, byzantium,
// constantinople, istanbul and petersburg instructions. // constantinople, istanbul and petersburg instructions.
func newIstanbulInstructionSet() JumpTable { func newIstanbulInstructionSet() *JumpTable {
instructionSet := newConstantinopleInstructionSet() instructionSet := newConstantinopleInstructionSet()
enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344 enable1344(instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344
enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 enable1884(instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 enable2200(instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
return validate(instructionSet) return validate(instructionSet)
} }
// newConstantinopleInstructionSet returns the frontier, homestead, // newConstantinopleInstructionSet returns the frontier, homestead,
// byzantium and constantinople instructions. // byzantium and constantinople instructions.
func newConstantinopleInstructionSet() JumpTable { func newConstantinopleInstructionSet() *JumpTable {
instructionSet := newByzantiumInstructionSet() instructionSet := newByzantiumInstructionSet()
instructionSet[SHL] = &operation{ instructionSet[SHL] = &operation{
execute: opSHL, execute: opSHL,
@ -179,7 +179,7 @@ func newConstantinopleInstructionSet() JumpTable {
// newByzantiumInstructionSet returns the frontier, homestead and // newByzantiumInstructionSet returns the frontier, homestead and
// byzantium instructions. // byzantium instructions.
func newByzantiumInstructionSet() JumpTable { func newByzantiumInstructionSet() *JumpTable {
instructionSet := newSpuriousDragonInstructionSet() instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = &operation{ instructionSet[STATICCALL] = &operation{
execute: opStaticCall, execute: opStaticCall,
@ -214,14 +214,14 @@ func newByzantiumInstructionSet() JumpTable {
} }
// EIP 158 a.k.a Spurious Dragon // EIP 158 a.k.a Spurious Dragon
func newSpuriousDragonInstructionSet() JumpTable { func newSpuriousDragonInstructionSet() *JumpTable {
instructionSet := newTangerineWhistleInstructionSet() instructionSet := newTangerineWhistleInstructionSet()
instructionSet[EXP].dynamicGas = gasExpEIP158 instructionSet[EXP].dynamicGas = gasExpEIP158
return validate(instructionSet) return validate(instructionSet)
} }
// EIP 150 a.k.a Tangerine Whistle // EIP 150 a.k.a Tangerine Whistle
func newTangerineWhistleInstructionSet() JumpTable { func newTangerineWhistleInstructionSet() *JumpTable {
instructionSet := newHomesteadInstructionSet() instructionSet := newHomesteadInstructionSet()
instructionSet[BALANCE].constantGas = params.BalanceGasEIP150 instructionSet[BALANCE].constantGas = params.BalanceGasEIP150
instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150 instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150
@ -235,7 +235,7 @@ func newTangerineWhistleInstructionSet() JumpTable {
// newHomesteadInstructionSet returns the frontier and homestead // newHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase. // instructions that can be executed during the homestead phase.
func newHomesteadInstructionSet() JumpTable { func newHomesteadInstructionSet() *JumpTable {
instructionSet := newFrontierInstructionSet() instructionSet := newFrontierInstructionSet()
instructionSet[DELEGATECALL] = &operation{ instructionSet[DELEGATECALL] = &operation{
execute: opDelegateCall, execute: opDelegateCall,
@ -250,7 +250,7 @@ func newHomesteadInstructionSet() JumpTable {
// newFrontierInstructionSet returns the frontier instructions // newFrontierInstructionSet returns the frontier instructions
// that can be executed during the frontier phase. // that can be executed during the frontier phase.
func newFrontierInstructionSet() JumpTable { func newFrontierInstructionSet() *JumpTable {
tbl := JumpTable{ tbl := JumpTable{
STOP: { STOP: {
execute: opStop, execute: opStop,
@ -1061,7 +1061,7 @@ func newFrontierInstructionSet() JumpTable {
} }
} }
return validate(tbl) return validate(&tbl)
} }
func copyJumpTable(source *JumpTable) *JumpTable { func copyJumpTable(source *JumpTable) *JumpTable {

View file

@ -24,7 +24,7 @@ import (
// LookupInstructionSet returns the instruction set for the fork configured by // LookupInstructionSet returns the instruction set for the fork configured by
// the rules. // the rules.
func LookupInstructionSet(rules params.Rules) (JumpTable, error) { func LookupInstructionSet(rules params.Rules) (*JumpTable, error) {
switch { switch {
case rules.IsVerkle: case rules.IsVerkle:
return newCancunInstructionSet(), errors.New("verkle-fork not defined yet") return newCancunInstructionSet(), errors.New("verkle-fork not defined yet")

View file

@ -28,7 +28,7 @@ func TestJumpTableCopy(t *testing.T) {
require.Equal(t, uint64(0), tbl[SLOAD].constantGas) require.Equal(t, uint64(0), tbl[SLOAD].constantGas)
// a deep copy won't modify the shared jump table // a deep copy won't modify the shared jump table
deepCopy := copyJumpTable(&tbl) deepCopy := copyJumpTable(tbl)
deepCopy[SLOAD].constantGas = 100 deepCopy[SLOAD].constantGas = 100
require.Equal(t, uint64(100), deepCopy[SLOAD].constantGas) require.Equal(t, uint64(100), deepCopy[SLOAD].constantGas)
require.Equal(t, uint64(0), tbl[SLOAD].constantGas) require.Equal(t, uint64(0), tbl[SLOAD].constantGas)