mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +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 (
|
var (
|
||||||
bigZero = new(big.Int)
|
bigZero = new(big.Int)
|
||||||
|
tt255 = math.BigPow(2, 255)
|
||||||
|
tt256 = math.BigPow(2, 256)
|
||||||
errWriteProtection = errors.New("evm: write protection")
|
errWriteProtection = errors.New("evm: write protection")
|
||||||
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
|
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
|
||||||
errExecutionReverted = errors.New("evm: execution reverted")
|
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) {
|
func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := math.S256(stack.pop()), math.S256(stack.pop())
|
x, y := stack.pop(), stack.peek()
|
||||||
if x.Cmp(math.S256(y)) < 0 {
|
|
||||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
||||||
} else {
|
|
||||||
stack.push(new(big.Int))
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := math.S256(stack.pop()), math.S256(stack.pop())
|
x, y := stack.pop(), stack.peek()
|
||||||
if x.Cmp(y) > 0 {
|
|
||||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
|
||||||
} else {
|
|
||||||
stack.push(new(big.Int))
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
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 {
|
if x.Cmp(y) == 0 {
|
||||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
y.SetUint64(1)
|
||||||
} else {
|
} else {
|
||||||
stack.push(new(big.Int))
|
y.SetUint64(0)
|
||||||
}
|
}
|
||||||
|
evm.interpreter.intPool.put(x)
|
||||||
evm.interpreter.intPool.put(x, y)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x := stack.pop()
|
x := stack.peek()
|
||||||
if x.Sign() > 0 {
|
if x.Sign() > 0 {
|
||||||
stack.push(new(big.Int))
|
x.SetUint64(0)
|
||||||
} else {
|
} else {
|
||||||
stack.push(evm.interpreter.intPool.get().SetUint64(1))
|
x.SetUint64(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.interpreter.intPool.put(x)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,11 @@ func BenchmarkOpEq(b *testing.B) {
|
||||||
|
|
||||||
opBenchmark(b, opEq, x, y)
|
opBenchmark(b, opEq, x, y)
|
||||||
}
|
}
|
||||||
|
func BenchmarkOpEq2(b *testing.B) {
|
||||||
|
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
|
||||||
|
y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe"
|
||||||
|
opBenchmark(b, opEq, x, y)
|
||||||
|
}
|
||||||
func BenchmarkOpAnd(b *testing.B) {
|
func BenchmarkOpAnd(b *testing.B) {
|
||||||
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
x := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
||||||
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
y := "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
|
@ -412,3 +416,7 @@ func BenchmarkOpSAR(b *testing.B) {
|
||||||
|
|
||||||
opBenchmark(b, opSAR, x, y)
|
opBenchmark(b, opSAR, x, y)
|
||||||
}
|
}
|
||||||
|
func BenchmarkOpIsZero(b *testing.B) {
|
||||||
|
x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff"
|
||||||
|
opBenchmark(b, opIszero, x)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue