diff options
author | dm4 <dm4@skymizer.com> | 2019-04-10 18:03:29 +0800 |
---|---|---|
committer | hydai <hydai@skymizer.com> | 2019-04-11 18:22:55 +0800 |
commit | 0f7acecfe78a32cf51153f6996969ad67e989ada (patch) | |
tree | ca057aa298b3dd249030372fd31f9f0710f4dfd1 | |
parent | 657c43d91c1f5d63a20e29414b87eaa5af6e3fd5 (diff) | |
download | dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar.gz dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar.bz2 dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar.lz dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar.xz dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.tar.zst dexon-0f7acecfe78a32cf51153f6996969ad67e989ada.zip |
[WIP] cache wasm module & vm
-rw-r--r-- | core/vm/dvm/dvm.go | 44 | ||||
-rw-r--r-- | vendor/github.com/go-interpreter/wagon/exec/vm.go | 1 |
2 files changed, 32 insertions, 13 deletions
diff --git a/core/vm/dvm/dvm.go b/core/vm/dvm/dvm.go index 9dd59dc3e..c4812e637 100644 --- a/core/vm/dvm/dvm.go +++ b/core/vm/dvm/dvm.go @@ -90,6 +90,9 @@ type DVM struct { meteringContract *vm.Contract meteringModule *wasm.Module meteringStartIndex int64 + + moduleCache map[common.Hash]*wasm.Module + vmCache map[common.Hash]*exec.VM } type Config struct { @@ -107,9 +110,11 @@ func NewDVM(statedb vm.StateDB, config Config) *DVM { Transfer: core.Transfer, } dvm := &DVM{ - Context: ctx, - statedb: statedb, - metering: config.Metering, + Context: ctx, + statedb: statedb, + metering: config.Metering, + moduleCache: make(map[common.Hash]*wasm.Module), + vmCache: make(map[common.Hash]*exec.VM), } if dvm.metering { @@ -448,18 +453,31 @@ func (dvm *DVM) run(contract *vm.Contract, input []byte, ro bool) ([]byte, error dvm.contract = contract dvm.contract.Input = input - module, err := wasm.ReadModule(bytes.NewReader(contract.Code), WrappedModuleResolver(dvm)) - if err != nil { - dvm.terminationType = TerminateInvalid - return nil, fmt.Errorf("Error decoding module at address %s: %v", contract.Address().Hex(), err) + module, ok := dvm.moduleCache[contract.CodeHash] + if !ok { + var err error + module, err = wasm.ReadModule(bytes.NewReader(contract.Code), WrappedModuleResolver(dvm)) + if err != nil { + dvm.terminationType = TerminateInvalid + return nil, fmt.Errorf("Error decoding module at address %s: %v", contract.Address().Hex(), err) + } + dvm.moduleCache[contract.CodeHash] = module } - - wavm, err := exec.NewVM(module) - if err != nil { - dvm.terminationType = TerminateInvalid - return nil, fmt.Errorf("could not create the vm: %v", err) + wavm, ok := dvm.vmCache[contract.CodeHash] + if !ok { + var err error + wavm, err = exec.NewVM(module) + if err != nil { + dvm.terminationType = TerminateInvalid + return nil, fmt.Errorf("could not create the vm: %v", err) + } + wavm.RecoverPanic = true + dvm.vmCache[contract.CodeHash] = wavm + } else { + // reset memory if cache hit + copy(wavm.Memory(), module.LinearMemoryIndexSpace[0]) } - wavm.RecoverPanic = true + dvm.vm = wavm mainIndex, err := validateModule(module) diff --git a/vendor/github.com/go-interpreter/wagon/exec/vm.go b/vendor/github.com/go-interpreter/wagon/exec/vm.go index 04b56adc1..7074d8e3a 100644 --- a/vendor/github.com/go-interpreter/wagon/exec/vm.go +++ b/vendor/github.com/go-interpreter/wagon/exec/vm.go @@ -296,6 +296,7 @@ func (vm *VM) ExecCode(fnIndex int64, args ...uint64) (rtrn interface{}, err err vm.ctx.pc = 0 vm.ctx.code = compiled.code vm.ctx.curFunc = fnIndex + vm.abort = false for i, arg := range args { vm.ctx.locals[i] = arg |