evm: less defers in interpreter (#8179)

This commit is contained in:
Alex Sharov 2023-09-25 08:53:04 +07:00 committed by GitHub
parent a22ab813af
commit 5641b52be0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -183,17 +183,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
return nil, nil
}
// Increment the call depth which is restricted to 1024
in.depth++
defer in.decrementDepth()
// Make sure the readOnly is only set if we aren't in readOnly yet.
// This makes also sure that the readOnly flag isn't removed for child calls.
if readOnly && !in.readOnly {
in.readOnly = true
defer func() { in.readOnly = false }()
}
// Reset the previous call's return data. It's unimportant to preserve the old buffer
// as every returning call will return new data anyway.
in.returnData = nil
@ -219,25 +208,37 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
logged bool // deferred Tracer should ignore already logged steps
res []byte // result of the opcode execution function
)
// Don't move this deferrred function, it's placed before the capturestate-deferred method,
// so that it get's executed _after_: the capturestate needs the stacks before
// they are returned to the pools
mem.Reset()
defer pool.Put(mem)
defer stack.ReturnNormalStack(locStack)
contract.Input = input
if in.cfg.Debug {
defer func() {
if err != nil {
if !logged {
in.cfg.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.depth, err) //nolint:errcheck
} else {
in.cfg.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.depth, err)
}
}
}()
// Make sure the readOnly is only set if we aren't in readOnly yet.
// This makes also sure that the readOnly flag isn't removed for child calls.
restoreReadonly := readOnly && !in.readOnly
if restoreReadonly {
in.readOnly = true
}
// Increment the call depth which is restricted to 1024
in.depth++
defer func() {
// first: capture data/memory/state/depth/etc... then clenup them
if in.cfg.Debug && err != nil {
if !logged {
in.cfg.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.depth, err) //nolint:errcheck
} else {
in.cfg.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.depth, err)
}
}
// this function must execute _after_: the `CaptureState` needs the stacks before
pool.Put(mem)
stack.ReturnNormalStack(locStack)
if restoreReadonly {
in.readOnly = false
}
in.depth--
}()
// The Interpreter main run loop (contextual). This loop runs until either an
// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
// the execution of one of the operations or until the done flag is set by the