Skip to content

Commit

Permalink
fix: recursive for large and deep struct
Browse files Browse the repository at this point in the history
  • Loading branch information
liuq19 committed Apr 18, 2024
1 parent 56b47ab commit 05aa8b1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
15 changes: 15 additions & 0 deletions dev/decoder/compile_struct.go
Expand Up @@ -9,6 +9,10 @@ import (
"github.com/bytedance/sonic/dev/internal/caching"
)

const (
_MAX_FIELDS = 50 // cutoff at 50 fields struct
)

func (c *compiler) compileIntStringOption(vt reflect.Type) decFunc {
switch vt.Size() {
case 4:
Expand Down Expand Up @@ -80,9 +84,20 @@ func (c *compiler) compileFieldStringOption(vt reflect.Type) decFunc {
}
}


func (c *compiler) compileStruct(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
if c.depth >= c.opts.MaxInlineDepth || (c.counts > 0 && vt.NumField() >= _MAX_FIELDS) {
return &recuriveDecoder{
typ: rt.UnpackType(vt),
}
} else {
return c.compileStructBody(vt)
}
}

func (c *compiler) compileStructBody(vt reflect.Type) decFunc {
fv := resolver.ResolveStruct(vt)
fm := caching.CreateFieldMap(len(fv))

Expand Down
15 changes: 14 additions & 1 deletion dev/decoder/compiler.go
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"reflect"

"github.com/bytedance/sonic/option"
"github.com/bytedance/sonic/dev/internal/rt"
"github.com/bytedance/sonic/dev/internal/caching"
)
Expand All @@ -30,15 +31,22 @@ func findOrCompile(vt *rt.GoType) (decFunc, error) {
type compiler struct {
visited map[reflect.Type]bool
depth int
counts int
opts option.CompileOptions
}

func newCompiler() *compiler {
return &compiler{
visited: make(map[reflect.Type]bool),
depth: 0,
opts: option.DefaultCompileOptions(),
}
}

func (self *compiler) apply(opts option.CompileOptions) *compiler {
self.opts = opts
return self
}

const _CompileMaxDepth = 4096

func (c *compiler) enter(vt reflect.Type) {
Expand Down Expand Up @@ -113,6 +121,9 @@ func (c *compiler) compile(vt reflect.Type) decFunc {
}

func (c *compiler) compileBasic(vt reflect.Type) decFunc {
defer func() {
c.counts += 1
}()
switch vt.Kind() {
case reflect.Bool:
return &boolDecoder{}
Expand Down Expand Up @@ -279,6 +290,8 @@ func (c *compiler) compileSliceBytes(vt reflect.Type) decFunc {
}

func (c *compiler) compileInterface(vt reflect.Type) decFunc {
c.enter(vt)
defer c.exit(vt)
if vt.NumMethod() == 0 {
return &efaceDecoder{}
}
Expand Down
Binary file modified dev/internal/link/libsonic_rs_x86_64-unknown-linux-gnu.so
Binary file not shown.

0 comments on commit 05aa8b1

Please sign in to comment.