Skip to content

Commit

Permalink
feat:(option) add option MaxInlineDepth for addjust compilation inl…
Browse files Browse the repository at this point in the history
…ine depth (#287)

* feat: make compilation depth changeable

* feat: add option `DefaultMaxInlineDepth`

* add recurse depth = 10

* refactor

* doc: readme and comment

* opt: add `_MAX_FIELDS` to limit the inlining of big struct

* update license

* fix typo
  • Loading branch information
AsterDY authored Aug 22, 2022
1 parent 1a7758c commit 94f95f0
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 36 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,18 @@ import (

func init() {
var v HugeStruct
// For most large types (nesting depth <= 5)

// For most large types (nesting depth <= option.DefaultMaxInlineDepth)
err := sonic.Pretouch(reflect.TypeOf(v))
// If the type is too deep nesting (nesting depth > 5),
// you can set compile recursive depth in Pretouch for better stability in JIT.
err := sonic.Pretouch(reflect.TypeOf(v), option.WithCompileRecursiveDepth(depth))

// with more CompileOption...
err := sonic.Pretouch(reflect.TypeOf(v),
// If the type is too deep nesting (nesting depth > option.DefaultMaxInlineDepth),
// you can set compile recursive loops in Pretouch for better stability in JIT.
option.WithCompileRecursiveDepth(loop),
// For large nested struct, try to set smaller depth to reduce compiling time.
option.WithCompileMaxInlineDepth(depth),
)
}
```

Expand Down
15 changes: 7 additions & 8 deletions decoder/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ const (
)

const (
_MAX_STACK = 5 // cutoff at 5 levels of nesting types
_MAX_ILBUF = 100000 // cutoff at 100k of IL instructions
_MAX_FIELDS = 50 // cutoff at 50 fields struct
)

var _OpNames = [256]string {
Expand Down Expand Up @@ -487,15 +487,14 @@ type _Compiler struct {

func newCompiler() *_Compiler {
return &_Compiler {
opts: option.DefaultCompileOptions(),
tab: map[reflect.Type]bool{},
rec: map[reflect.Type]bool{},
}
}

func (self *_Compiler) apply(opts option.CompileOptions) *_Compiler {
self.opts = opts
if self.opts.RecursiveDepth > 0 {
self.rec = map[reflect.Type]bool{}
}
return self
}

Expand All @@ -516,15 +515,15 @@ func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) {
}

func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
ok := self.tab[vt]
pt := reflect.PtrTo(vt)

/* check for recursive nesting */
ok := self.tab[vt]
if ok {
p.rtt(_OP_recurse, vt)
return
}

pt := reflect.PtrTo(vt)

/* check for `json.Unmarshaler` with pointer receiver */
if pt.Implements(jsonUnmarshalerType) {
p.rtt(_OP_unmarshal_p, pt)
Expand Down Expand Up @@ -812,7 +811,7 @@ func (self *_Compiler) compileStringBody(p *_Program) {
}

func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) {
if sp >= _MAX_STACK || p.pc() >= _MAX_ILBUF {
if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) {
p.rtt(_OP_recurse, vt)
if self.opts.RecursiveDepth > 0 {
self.rec[vt] = true
Expand Down
5 changes: 2 additions & 3 deletions decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
cfg := option.DefaultCompileOptions()
for _, opt := range opts {
opt(&cfg)
break
}
return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
}
Expand Down Expand Up @@ -189,12 +188,12 @@ func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
return nil
}
next := make(map[reflect.Type]bool)
for vt, _ := range(vtm) {
for vt := range(vtm) {
sub, err := pretouchType(vt, opts)
if err != nil {
return err
}
for svt, _ := range(sub) {
for svt := range(sub) {
next[svt] = true
}
}
Expand Down
6 changes: 4 additions & 2 deletions encoder/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ const (
)

const (
_MAX_STACK = 5 // cutoff at 5 levels of nesting types
_MAX_ILBUF = 100000 // cutoff at 100k of IL instructions
_MAX_FIELDS = 50 // cutoff at 50 fields struct
)

var _OpNames = [256]string {
Expand Down Expand Up @@ -384,7 +384,9 @@ type _Compiler struct {

func newCompiler() *_Compiler {
return &_Compiler {
opts: option.DefaultCompileOptions(),
tab: map[reflect.Type]bool{},
rec: map[reflect.Type]bool{},
}
}

Expand Down Expand Up @@ -658,7 +660,7 @@ func (self *_Compiler) compileString(p *_Program, vt reflect.Type) {
}

func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) {
if sp >= _MAX_STACK || p.pc() >= _MAX_ILBUF {
if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) {
p.rtt(_OP_recurse, vt)
if self.opts.RecursiveDepth > 0 {
self.rec[vt] = true
Expand Down
4 changes: 2 additions & 2 deletions encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
return nil
}
next := make(map[reflect.Type]bool)
for vt, _ := range(vtm) {
for vt := range(vtm) {
sub, err := pretouchType(vt, opts)
if err != nil {
return err
}
for svt, _ := range(sub) {
for svt := range(sub) {
next[svt] = true
}
}
Expand Down
Loading

0 comments on commit 94f95f0

Please sign in to comment.