diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-11-13 22:09:28 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:53 +0800 |
commit | c1138b576524413f8d5755f77aaebd759d6317fc (patch) | |
tree | f237a6de9aea1d41a175a71a90a622312740e8c3 /core/vm/instructions.go | |
parent | 16122f0041756465198c560d9a486f610efcc787 (diff) | |
download | dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar.gz dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar.bz2 dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar.lz dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar.xz dexon-c1138b576524413f8d5755f77aaebd759d6317fc.tar.zst dexon-c1138b576524413f8d5755f77aaebd759d6317fc.zip |
core: vm: Optimize evm (#13)
* core: vm: add an EVM benchmark
* core: vm: optimize stack allocation and instruction for calculating 2^n
* Add DEXONBet bench
Diffstat (limited to 'core/vm/instructions.go')
-rw-r--r-- | core/vm/instructions.go | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/core/vm/instructions.go b/core/vm/instructions.go index de0fcaeb6..499e066f7 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -32,13 +32,24 @@ import ( var ( bigZero = new(big.Int) + big2 = big.NewInt(2) + big256 = big.NewInt(256) tt255 = math.BigPow(2, 255) errWriteProtection = errors.New("evm: write protection") errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") errExecutionReverted = errors.New("evm: execution reverted") errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded") + power2 = make([]*big.Int, 256) ) +func init() { + cur := int64(1) + for i := 0; i < 256; i++ { + power2[i] = big.NewInt(cur) + cur <<= 1 + } +} + func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() math.U256(y.Add(x, y)) @@ -126,22 +137,15 @@ func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory func opExp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { base, exponent := stack.pop(), stack.pop() - // some shortcuts - cmpToOne := exponent.Cmp(big1) - if cmpToOne < 0 { // Exponent is zero - // x ^ 0 == 1 - stack.push(base.SetUint64(1)) - } else if base.Sign() == 0 { - // 0 ^ y, if y != 0, == 0 - stack.push(base.SetUint64(0)) - } else if cmpToOne == 0 { // Exponent is one - // x ^ 1 == x - stack.push(base) + if base.Cmp(big2) == 0 && exponent.Cmp(big256) == -1 { + exp := exponent.Int64() + stack.push(interpreter.intPool.get().Set(power2[exp])) } else { stack.push(math.Exp(base, exponent)) - interpreter.intPool.put(base) } - interpreter.intPool.put(exponent) + + interpreter.intPool.put(base, exponent) + return nil, nil } |