From ea2718c9462ae351baab5eaa05a7e1ef9dc916fa Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 29 May 2015 14:40:45 +0200 Subject: core/vm: improve JUMPDEST analysis * JUMPDEST analysis is faster because less type conversions are performed. * The map of JUMPDEST locations is now created lazily at the first JUMP. * The result of the analysis is kept around for recursive invocations through CALL/CALLCODE. Fixes #1147 --- core/vm/vm.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'core/vm/vm.go') diff --git a/core/vm/vm.go b/core/vm/vm.go index 6db99bdcc..0d8facbb6 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -72,17 +72,16 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { } var ( - op OpCode - - destinations = analyseJumpDests(context.Code) - mem = NewMemory() - stack = newStack() - pc = new(big.Int) - statedb = self.env.State() + op OpCode + codehash = crypto.Sha3Hash(code) + mem = NewMemory() + stack = newStack() + pc = new(big.Int) + statedb = self.env.State() jump = func(from *big.Int, to *big.Int) error { - nop := context.GetOp(to) - if !destinations.Has(to) { + if !context.jumpdests.has(codehash, code, to) { + nop := context.GetOp(to) return fmt.Errorf("invalid jump destination (%v) %v", nop, to) } -- cgit v1.2.3 From 48fb0c3213a1634a266dd661d30c9ecd3c352f49 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 29 May 2015 14:58:57 +0200 Subject: core/vm: check for 'no code' before doing any work --- core/vm/vm.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'core/vm/vm.go') diff --git a/core/vm/vm.go b/core/vm/vm.go index 0d8facbb6..2bd950385 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -71,6 +71,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { } } + // Don't bother with the execution if there's no code. + if len(code) == 0 { + return context.Return(nil), nil + } + var ( op OpCode codehash = crypto.Sha3Hash(code) @@ -94,11 +99,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { } ) - // Don't bother with the execution if there's no code. - if len(code) == 0 { - return context.Return(nil), nil - } - for { // The base for all big integer arithmetic base := new(big.Int) -- cgit v1.2.3