summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/internal/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/decoder')
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go2
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go12
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go3
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/compiler.go45
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go6
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s2
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/stream.go205
7 files changed, 154 insertions, 121 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go b/vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go
index 5db5b5cd0..6adeac0cf 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go
@@ -1,4 +1,4 @@
-// +build go1.21,!go1.22
+// +build go1.21,!go1.23
// Copyright 2023 CloudWeGo Authors
//
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go
index 3d223e14e..0defb75a5 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go
@@ -1,5 +1,4 @@
-//go:build go1.17 && !go1.22
-// +build go1.17,!go1.22
+// +build go1.17,!go1.23
/*
* Copyright 2021 ByteDance Inc.
@@ -420,9 +419,9 @@ func (self *_Assembler) call_go(fn obj.Addr) {
}
func (self *_Assembler) callc(fn obj.Addr) {
- self.Emit("XCHGQ", _IP, _BP)
+ self.save(_IP)
self.call(fn)
- self.Emit("XCHGQ", _IP, _BP)
+ self.load(_IP)
}
func (self *_Assembler) call_c(fn obj.Addr) {
@@ -1164,7 +1163,7 @@ var (
var (
_F_FieldMap_GetCaseInsensitive obj.Addr
- _Empty_Slice = make([]byte, 0)
+ _Empty_Slice = []byte{}
_Zero_Base = int64(uintptr(((*rt.GoSlice)(unsafe.Pointer(&_Empty_Slice))).Ptr))
)
@@ -1641,7 +1640,8 @@ func (self *_Assembler) _asm_OP_check_empty(p *_Instr) {
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
- self.StorePtr(_Zero_Base, jit.Ptr(_VP, 0), _AX) // MOVQ $zerobase, (VP)
+ self.Emit("MOVQ", jit.Imm(_Zero_Base), _AX)
+ self.WritePtrAX(9, jit.Ptr(_VP, 0), false)
self.Emit("PXOR", _X0, _X0) // PXOR X0, X0
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go
index 57a38b420..9e2acc23f 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go
@@ -1651,7 +1651,8 @@ func (self *_Assembler) _asm_OP_check_empty(p *_Instr) {
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
- self.StorePtr(_Zero_Base, jit.Ptr(_VP, 0), _AX) // MOVQ $zerobase, (VP)
+ self.Emit("MOVQ", jit.Imm(_Zero_Base), _AX)
+ self.WritePtrAX(9, jit.Ptr(_VP, 0), false)
self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/compiler.go b/vendor/github.com/bytedance/sonic/internal/decoder/compiler.go
index e9e2b77fc..b350c0461 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/compiler.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/compiler.go
@@ -527,40 +527,47 @@ func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) {
return
}
-func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
- /* check for recursive nesting */
- ok := self.tab[vt]
- if ok {
- p.rtt(_OP_recurse, vt)
- return
- }
-
+func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type) bool {
pt := reflect.PtrTo(vt)
/* check for `json.Unmarshaler` with pointer receiver */
if pt.Implements(jsonUnmarshalerType) {
p.rtt(_OP_unmarshal_p, pt)
- return
+ return true
}
/* check for `json.Unmarshaler` */
if vt.Implements(jsonUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalJson(p, vt)
- return
+ return true
}
/* check for `encoding.TextMarshaler` with pointer receiver */
if pt.Implements(encodingTextUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalTextPtr(p, pt)
- return
+ return true
}
/* check for `encoding.TextUnmarshaler` */
if vt.Implements(encodingTextUnmarshalerType) {
p.add(_OP_lspace)
self.compileUnmarshalText(p, vt)
+ return true
+ }
+ return false
+}
+
+func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
+ /* check for recursive nesting */
+ ok := self.tab[vt]
+ if ok {
+ p.rtt(_OP_recurse, vt)
+ return
+ }
+
+ if self.checkMarshaler(p, vt) {
return
}
@@ -683,17 +690,9 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
/* dereference all the way down */
for et.Kind() == reflect.Ptr {
- if et.Implements(jsonUnmarshalerType) {
- p.rtt(_OP_unmarshal_p, et)
+ if self.checkMarshaler(p, et) {
return
}
-
- if et.Implements(encodingTextUnmarshalerType) {
- p.add(_OP_lspace)
- self.compileUnmarshalTextPtr(p, et)
- return
- }
-
et = et.Elem()
p.rtt(_OP_deref, et)
}
@@ -706,7 +705,7 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
/* enter the recursion */
p.add(_OP_lspace)
self.tab[et] = true
-
+
/* not inline the pointer type
* recursing the defined pointer type's elem will casue issue379.
*/
@@ -716,8 +715,12 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
j := p.pc()
p.add(_OP_goto)
+
+ // set val pointer as nil
p.pin(i)
p.add(_OP_nil_1)
+
+ // nothing todo
p.pin(j)
}
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go
index 337af054c..c7514cb41 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go
@@ -1,4 +1,4 @@
-// +build go1.17,!go1.22
+// +build go1.17,!go1.23
/*
* Copyright 2021 ByteDance Inc.
@@ -119,9 +119,9 @@ func (self *_ValueDecoder) call_go(fn obj.Addr) {
}
func (self *_ValueDecoder) callc(fn obj.Addr) {
- self.Emit("XCHGQ", _IP, _BP)
+ self.save(_IP)
self.call(fn)
- self.Emit("XCHGQ", _IP, _BP)
+ self.load(_IP)
}
func (self *_ValueDecoder) call_c(fn obj.Addr) {
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s b/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s
index 1c46928de..b4b0de183 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s
@@ -1,4 +1,4 @@
-// +build go1.17,!go1.22
+// +build go1.17,!go1.23
//
// Copyright 2021 ByteDance Inc.
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/stream.go b/vendor/github.com/bytedance/sonic/internal/decoder/stream.go
index a3716435a..7eb8a6951 100644
--- a/vendor/github.com/bytedance/sonic/internal/decoder/stream.go
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/stream.go
@@ -23,11 +23,12 @@ import (
`github.com/bytedance/sonic/internal/native`
`github.com/bytedance/sonic/internal/native/types`
+ `github.com/bytedance/sonic/internal/rt`
`github.com/bytedance/sonic/option`
)
var (
- minLeftBufferShift uint = 1
+ minLeftBufferShift uint = 1
)
// StreamDecoder is the decoder context object for streaming input.
@@ -58,95 +59,71 @@ func NewStreamDecoder(r io.Reader) *StreamDecoder {
// Either io error from underlying io.Reader (except io.EOF)
// or syntax error from data will be recorded and stop subsequently decoding.
func (self *StreamDecoder) Decode(val interface{}) (err error) {
- if self.err != nil {
- return self.err
- }
-
- var buf = self.buf[self.scanp:]
- var p = 0
- var recycle bool
- if cap(buf) == 0 {
- buf = bufPool.Get().([]byte)
- recycle = true
- }
-
- var first = true
- var repeat = true
-
-read_more:
- for {
- l := len(buf)
- realloc(&buf)
- n, err := self.r.Read(buf[l:cap(buf)])
- buf = buf[:l+n]
- if err != nil {
- repeat = false
- if err == io.EOF {
- if len(buf) == 0 {
- return err
- }
- break
- }
- self.err = err
- return err
- }
- if n > 0 || first {
- break
- }
- }
- first = false
-
- l := len(buf)
- if l > 0 {
- self.Decoder.Reset(string(buf))
-
- var x int
- if ret := native.SkipOneFast(&self.s, &x); ret < 0 {
- if repeat {
- goto read_more
+ // read more data into buf
+ if self.More() {
+ // println(string(self.buf))
+ var s = self.scanp
+ try_skip:
+ var e = len(self.buf)
+ // println("s:", s, "e:", e, "scanned:",self.scanned, "scanp:",self.scanp, self.buf)
+ var src = rt.Mem2Str(self.buf[s:e])
+ // if len(src) > 5 {
+ // println(src[:5], src[len(src)-5:])
+ // } else {
+ // println(src)
+ // }
+ // try skip
+ var x = 0;
+ if y := native.SkipOneFast(&src, &x); y < 0 {
+ if self.readMore() {
+ // println("more")
+ goto try_skip
} else {
- err = SyntaxError{x, self.s, types.ParsingError(-ret), ""}
- self.err = err
+ // println("no more")
+ err = SyntaxError{e, self.s, types.ParsingError(-s), ""}
+ self.setErr(err)
return
}
+ } else {
+ s = y + s
+ e = x + s
}
-
+
+ // println("decode: ", s, e)
+ // must copy string here for safety
+ self.Decoder.Reset(string(self.buf[s:e]))
err = self.Decoder.Decode(val)
if err != nil {
- self.err = err
+ self.setErr(err)
+ return
}
- p = self.Decoder.Pos()
- self.scanned += int64(p)
- self.scanp = 0
- }
-
- if l > p {
- // remain undecoded bytes, so copy them into self.buf
- self.buf = append(self.buf[:0], buf[p:]...)
- } else {
- self.buf = nil
- recycle = true
- }
+ self.scanp = e
+ _, empty := self.scan()
+ if empty {
+ // println("recycle")
+ // no remain valid bytes, thus we just recycle buffer
+ mem := self.buf
+ self.buf = nil
+ bufPool.Put(mem[:0])
+ } else {
+ // println("keep")
+ // remain undecoded bytes, move them onto head
+ n := copy(self.buf, self.buf[self.scanp:])
+ self.buf = self.buf[:n]
+ }
- if recycle {
- buf = buf[:0]
- bufPool.Put(buf)
- }
- return err
-}
+ self.scanned += int64(self.scanp)
+ self.scanp = 0
+ }
-func (self StreamDecoder) repeatable(err error) bool {
- if ee, ok := err.(SyntaxError); ok &&
- (ee.Code == types.ERR_EOF || (ee.Code == types.ERR_INVALID_CHAR && self.i >= len(self.s)-1)) {
- return true
- }
- return false
+ return self.err
}
// InputOffset returns the input stream byte offset of the current decoder position.
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
func (self *StreamDecoder) InputOffset() int64 {
+ // println("input offset",self.scanned, self.scanp)
return self.scanned + int64(self.scanp)
}
@@ -166,28 +143,72 @@ func (self *StreamDecoder) More() bool {
return err == nil && c != ']' && c != '}'
}
+// More reports whether there is another element in the
+// current array or object being parsed.
+func (self *StreamDecoder) readMore() bool {
+ if self.err != nil {
+ return false
+ }
+
+ var err error
+ var n int
+ for {
+ // Grow buffer if not large enough.
+ l := len(self.buf)
+ realloc(&self.buf)
+
+ n, err = self.r.Read(self.buf[l:cap(self.buf)])
+ self.buf = self.buf[: l+n]
+
+ self.scanp = l
+ _, empty := self.scan()
+ if !empty {
+ return true
+ }
+
+ // buffer has been scanned, now report any error
+ if err != nil {
+ self.setErr(err)
+ return false
+ }
+ }
+}
+
+func (self *StreamDecoder) setErr(err error) {
+ self.err = err
+ mem := self.buf[:0]
+ self.buf = nil
+ bufPool.Put(mem)
+}
+
func (self *StreamDecoder) peek() (byte, error) {
var err error
for {
- for i := self.scanp; i < len(self.buf); i++ {
- c := self.buf[i]
- if isSpace(c) {
- continue
- }
- self.scanp = i
- return c, nil
+ c, empty := self.scan()
+ if !empty {
+ return byte(c), nil
}
// buffer has been scanned, now report any error
if err != nil {
- if err != io.EOF {
- self.err = err
- }
+ self.setErr(err)
return 0, err
}
err = self.refill()
}
}
+func (self *StreamDecoder) scan() (byte, bool) {
+ for i := self.scanp; i < len(self.buf); i++ {
+ c := self.buf[i]
+ if isSpace(c) {
+ continue
+ }
+ self.scanp = i
+ return c, false
+ }
+ return 0, true
+}
+
func isSpace(c byte) bool {
return types.SPACE_MASK & (1 << c) != 0
}
@@ -212,17 +233,25 @@ func (self *StreamDecoder) refill() error {
return err
}
-func realloc(buf *[]byte) {
+func realloc(buf *[]byte) bool {
l := uint(len(*buf))
c := uint(cap(*buf))
+ if c == 0 {
+ // println("use pool!")
+ *buf = bufPool.Get().([]byte)
+ return true
+ }
if c - l <= c >> minLeftBufferShift {
+ // println("realloc!")
e := l+(l>>minLeftBufferShift)
- if e < option.DefaultDecoderBufferSize {
- e = option.DefaultDecoderBufferSize
+ if e <= c {
+ e = c*2
}
tmp := make([]byte, l, e)
copy(tmp, *buf)
*buf = tmp
+ return true
}
+ return false
}