aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordm4 <dm4@skymizer.com>2019-04-10 18:03:29 +0800
committerhydai <hydai@skymizer.com>2019-04-11 18:22:55 +0800
commit0f7acecfe78a32cf51153f6996969ad67e989ada (patch)
treeca057aa298b3dd249030372fd31f9f0710f4dfd1
parent657c43d91c1f5d63a20e29414b87eaa5af6e3fd5 (diff)
downloaddexon-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.go44
-rw-r--r--vendor/github.com/go-interpreter/wagon/exec/vm.go1
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