mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
vm: optimize eq, slt, sgt and iszero + tests
This commit is contained in:
parent
3ec1b9a92d
commit
788755760c
2 changed files with 82 additions and 25 deletions
|
|
@ -30,6 +30,8 @@ import (
|
|||
|
||||
var (
|
||||
bigZero = new(big.Int)
|
||||
tt255 = math.BigPow(2, 255)
|
||||
tt256 = math.BigPow(2, 256)
|
||||
errWriteProtection = errors.New("evm: write protection")
|
||||
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
|
||||
errExecutionReverted = errors.New("evm: execution reverted")
|
||||
|
|
@ -191,50 +193,97 @@ func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack
|
|||
}
|
||||
|
||||
func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||
x, y := math.S256(stack.pop()), math.S256(stack.pop())
|
||||
if x.Cmp(math.S256(y)) < 0 {
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
||||
} else {
|
||||
stack.push(new(big.Int))
|
||||
}
|
||||
x, y := stack.pop(), stack.peek()
|
||||
|
||||
evm.interpreter.intPool.put(x, y)
|
||||
xSign := x.Cmp(tt255)
|
||||
ySign := y.Cmp(tt255)
|
||||
|
||||
if xSign >= 0 {
|
||||
//x negative
|
||||
if ySign < 0 {
|
||||
// y positive
|
||||
y.SetUint64(1)
|
||||
return nil, nil
|
||||
}
|
||||
// Both negative
|
||||
if x.Cmp(y) > 0 {
|
||||
y.SetUint64(1)
|
||||
} else {
|
||||
y.SetUint64(0)
|
||||
}
|
||||
} else {
|
||||
// x positive
|
||||
if ySign >= 0 {
|
||||
// y negative
|
||||
y.SetUint64(0)
|
||||
return nil, nil
|
||||
}
|
||||
// Both positive
|
||||
if x.Cmp(y) >= 0 {
|
||||
y.SetUint64(0)
|
||||
} else {
|
||||
y.SetUint64(1)
|
||||
}
|
||||
}
|
||||
evm.interpreter.intPool.put(x)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||
x, y := math.S256(stack.pop()), math.S256(stack.pop())
|
||||
if x.Cmp(y) > 0 {
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
||||
} else {
|
||||
stack.push(new(big.Int))
|
||||
}
|
||||
x, y := stack.pop(), stack.peek()
|
||||
|
||||
evm.interpreter.intPool.put(x, y)
|
||||
xSign := x.Cmp(tt255)
|
||||
ySign := y.Cmp(tt255)
|
||||
|
||||
if xSign >= 0 {
|
||||
//x negative
|
||||
if ySign < 0 {
|
||||
// y positive
|
||||
y.SetUint64(0)
|
||||
return nil, nil
|
||||
}
|
||||
// Both negative (note: equality -> 0)
|
||||
if x.Cmp(y) >= 0 {
|
||||
y.SetUint64(0)
|
||||
} else {
|
||||
y.SetUint64(1)
|
||||
}
|
||||
} else {
|
||||
// x positive
|
||||
if ySign >= 0 {
|
||||
// y negative
|
||||
y.SetUint64(1)
|
||||
return nil, nil
|
||||
}
|
||||
// Both positive
|
||||
if x.Cmp(y) > 0 {
|
||||
y.SetUint64(1)
|
||||
} else {
|
||||
y.SetUint64(0)
|
||||
}
|
||||
}
|
||||
evm.interpreter.intPool.put(x)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||
x, y := stack.pop(), stack.pop()
|
||||
x, y := stack.pop(), stack.peek()
|
||||
if x.Cmp(y) == 0 {
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
||||
y.SetUint64(1)
|
||||
} else {
|
||||
stack.push(new(big.Int))
|
||||
y.SetUint64(0)
|
||||
}
|
||||
|
||||
evm.interpreter.intPool.put(x, y)
|
||||
evm.interpreter.intPool.put(x)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||
x := stack.pop()
|
||||
x := stack.peek()
|
||||
if x.Sign() > 0 {
|
||||
stack.push(new(big.Int))
|
||||
x.SetUint64(0)
|
||||
} else {
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
||||
x.SetUint64(1)
|
||||
}
|
||||
|
||||
evm.interpreter.intPool.put(x)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,11 @@ func BenchmarkOpEq(b *testing.B) {
|
|||
|
||||
opBenchmark(b, opEq, x, y)
|
||||
}
|
||||
|
||||
func BenchmarkOpEq2(b *testing.B) {
|
||||
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
|
||||
y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe"
|
||||
opBenchmark(b, opEq, x, y)
|
||||
}
|
||||
func BenchmarkOpAnd(b *testing.B) {
|
||||
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
||||
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
||||
|
|
@ -412,3 +416,7 @@ func BenchmarkOpSAR(b *testing.B) {
|
|||
|
||||
opBenchmark(b, opSAR, x, y)
|
||||
}
|
||||
func BenchmarkOpIsZero(b *testing.B) {
|
||||
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
|
||||
opBenchmark(b, opIszero, x)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue