Commit 1569ff03 authored by vipwzw's avatar vipwzw

优化runtime cache 部分结构

parent 4c05a1f1
...@@ -8,11 +8,13 @@ import ( ...@@ -8,11 +8,13 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
ptypes "github.com/33cn/plugin/plugin/dapp/js/types" ptypes "github.com/33cn/plugin/plugin/dapp/js/types"
"github.com/33cn/plugin/plugin/dapp/js/types/jsproto" "github.com/33cn/plugin/plugin/dapp/js/types/jsproto"
lru "github.com/hashicorp/golang-lru"
"github.com/robertkrimen/otto" "github.com/robertkrimen/otto"
) )
var driverName = ptypes.JsX var driverName = ptypes.JsX
var basevm *otto.Otto var basevm *otto.Otto
var codecache *lru.Cache
func init() { func init() {
ety := types.LoadExecutorType(driverName) ety := types.LoadExecutorType(driverName)
...@@ -26,6 +28,12 @@ func init() { ...@@ -26,6 +28,12 @@ func init() {
//Init 插件初始化 //Init 插件初始化
func Init(name string, sub []byte) { func Init(name string, sub []byte) {
//最新的64个code做cache
var err error
codecache, err = lru.New(512)
if err != nil {
panic(err)
}
drivers.Register(GetName(), newjs, 0) drivers.Register(GetName(), newjs, 0)
} }
...@@ -53,10 +61,6 @@ func (u *js) GetDriverName() string { ...@@ -53,10 +61,6 @@ func (u *js) GetDriverName() string {
func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction, func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
index int, receiptData *types.ReceiptData) (*otto.Object, error) { index int, receiptData *types.ReceiptData) (*otto.Object, error) {
vm, err := u.createVM(payload.Name, tx, index)
if err != nil {
return nil, err
}
if payload.Args != "" { if payload.Args != "" {
newjson, err := rewriteJSON([]byte(payload.Args)) newjson, err := rewriteJSON([]byte(payload.Args))
if err != nil { if err != nil {
...@@ -66,17 +70,15 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction, ...@@ -66,17 +70,15 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
} else { } else {
payload.Args = "{}" payload.Args = "{}"
} }
db := u.GetStateDB() loglist, err := jslogs(receiptData)
code, err := db.Get(calcCodeKey(payload.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
loglist, err := jslogs(receiptData) vm, err := u.createVM(payload.Name, tx, index)
if err != nil { if err != nil {
return nil, err return nil, err
} }
vm.Set("loglist", loglist) vm.Set("loglist", loglist)
vm.Set("code", code)
if prefix == "init" { if prefix == "init" {
vm.Set("f", "init") vm.Set("f", "init")
} else { } else {
...@@ -84,7 +86,7 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction, ...@@ -84,7 +86,7 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
} }
vm.Set("args", payload.Args) vm.Set("args", payload.Args)
callfunc := "callcode(context, f, args, loglist)" callfunc := "callcode(context, f, args, loglist)"
jsvalue, err := vm.Run(string(code) + "\n" + callfunc) jsvalue, err := vm.Run(callfunc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -201,7 +203,20 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto ...@@ -201,7 +203,20 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto
if err != nil { if err != nil {
return nil, err return nil, err
} }
vm := basevm.Copy() var vm *otto.Otto
if vmitem, ok := codecache.Get(name); ok {
vm = vmitem.(*otto.Otto).Copy()
} else {
code, err := u.GetStateDB().Get(calcCodeKey(name))
if err != nil {
return nil, err
}
//cache 合约代码部分,不会cache 具体执行
cachevm := basevm.Copy()
cachevm.Run(code)
codecache.Add(name, cachevm)
vm = cachevm.Copy()
}
vm.Set("context", string(data)) vm.Set("context", string(data))
u.getstatedbFunc(vm, name) u.getstatedbFunc(vm, name)
u.getlocaldbFunc(vm, name) u.getlocaldbFunc(vm, name)
......
...@@ -69,12 +69,15 @@ Query.prototype.hello = function(args) { ...@@ -69,12 +69,15 @@ Query.prototype.hello = function(args) {
} }
` `
func init() {
Init("js", nil)
}
func initExec(ldb db.DB, kvdb db.KVDB, t assert.TestingT) *js { func initExec(ldb db.DB, kvdb db.KVDB, t assert.TestingT) *js {
e := newjs().(*js) e := newjs().(*js)
e.SetEnv(1, time.Now().Unix(), 1) e.SetEnv(1, time.Now().Unix(), 1)
e.SetLocalDB(kvdb) e.SetLocalDB(kvdb)
e.SetStateDB(kvdb) e.SetStateDB(kvdb)
c, tx := createCodeTx("test", jscode) c, tx := createCodeTx("test", jscode)
receipt, err := e.Exec_Create(c, tx, 0) receipt, err := e.Exec_Create(c, tx, 0)
assert.Nil(t, err) assert.Nil(t, err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment