mirror of
https://github.com/ii64/sonic.git
synced 2026-06-21 00:46:43 +08:00
fix: set _Stack.sp zero whenever put into pool (#132)
Co-authored-by: duanyi.aster <duanyi.aster@bytedance.com>
This commit is contained in:
parent
0f66ab7211
commit
ba4c2d2e55
4 changed files with 39 additions and 15 deletions
|
|
@ -982,6 +982,7 @@ func (self *_Assembler) _asm_OP_any(_ *_Instr) {
|
|||
self.Sjmp("JMP" , "_decode_end_{n}") // JMP _decode_end_{n}
|
||||
self.Link("_decode_{n}") // _decode_{n}:
|
||||
self.Emit("MOVQ" , _ARG_fv, _DF) // MOVQ fv, DF
|
||||
self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 0)) // MOVQ _ST, (SP)
|
||||
self.call(_F_decodeValue) // CALL decodeValue
|
||||
self.Emit("TESTQ" , _EP, _EP) // TESTQ EP, EP
|
||||
self.Sjmp("JNZ" , _LB_parsing_error) // JNZ _parsing_error
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package decoder
|
||||
|
||||
import (
|
||||
`runtime`
|
||||
`testing`
|
||||
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
|
|
@ -53,3 +54,15 @@ func TestErrors_ShortDescription(t *testing.T) {
|
|||
func TestErrors_EmptyDescription(t *testing.T) {
|
||||
println(make_err("", 0).Description())
|
||||
}
|
||||
|
||||
func TestDecoderErrorStackOverflower(t *testing.T) {
|
||||
src := `{"a":[]}`
|
||||
N := _MaxStack * runtime.GOMAXPROCS(0)
|
||||
for i:=0; i<N; i++ {
|
||||
var obj map[string]string
|
||||
err := NewDecoder(src).Decode(&obj)
|
||||
if err == nil || err.Error() != `Syntax error at index 5: invalid char` {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,26 +39,27 @@ import (
|
|||
*/
|
||||
|
||||
const (
|
||||
_VD_args = 64 // 64 bytes for passing arguments to other Go functions
|
||||
_VD_args = 8 // 8 bytes for passing arguments to this functions
|
||||
_VD_fargs = 64 // 64 bytes for passing arguments to other Go functions
|
||||
_VD_saves = 40 // 40 bytes for saving the registers before CALL instructions
|
||||
_VD_locals = 40 // 40 bytes for local variables
|
||||
)
|
||||
|
||||
const (
|
||||
_VD_offs = _VD_args + _VD_saves + _VD_locals
|
||||
_VD_offs = _VD_fargs + _VD_saves + _VD_locals
|
||||
_VD_size = _VD_offs + 8 // 8 bytes for the parent frame pointer
|
||||
)
|
||||
|
||||
var (
|
||||
_VAR_ss = _VAR_ss_Vt
|
||||
_VAR_df = jit.Ptr(_SP, _VD_args + _VD_saves)
|
||||
_VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves)
|
||||
)
|
||||
|
||||
var (
|
||||
_VAR_ss_Vt = jit.Ptr(_SP, _VD_args + _VD_saves + 8)
|
||||
_VAR_ss_Dv = jit.Ptr(_SP, _VD_args + _VD_saves + 16)
|
||||
_VAR_ss_Iv = jit.Ptr(_SP, _VD_args + _VD_saves + 24)
|
||||
_VAR_ss_Ep = jit.Ptr(_SP, _VD_args + _VD_saves + 32)
|
||||
_VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8)
|
||||
_VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16)
|
||||
_VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24)
|
||||
_VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32)
|
||||
)
|
||||
|
||||
type _ValueDecoder struct {
|
||||
|
|
@ -67,7 +68,7 @@ type _ValueDecoder struct {
|
|||
|
||||
func (self *_ValueDecoder) build() uintptr {
|
||||
self.Init(self.compile)
|
||||
return *(*uintptr)(self.Load("decode_value", _VD_size, 0))
|
||||
return *(*uintptr)(self.LoadWithFaker("decode_value", _VD_size, _VD_fargs, _Decoder_Generic_Shadow))
|
||||
}
|
||||
|
||||
/** Function Calling Helpers **/
|
||||
|
|
@ -77,7 +78,7 @@ func (self *_ValueDecoder) save(r ...obj.Addr) {
|
|||
if i > _VD_saves / 8 - 1 {
|
||||
panic("too many registers to save")
|
||||
} else {
|
||||
self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_args + int64(i) * 8))
|
||||
self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ func (self *_ValueDecoder) load(r ...obj.Addr) {
|
|||
if i > _VD_saves / 8 - 1 {
|
||||
panic("too many registers to load")
|
||||
} else {
|
||||
self.Emit("MOVQ", jit.Ptr(_SP, _VD_args + int64(i) * 8), v)
|
||||
self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,17 +64,25 @@ var errCallShadow = errors.New("DON'T CALL THIS!")
|
|||
|
||||
//go:nosplit
|
||||
// Faker func of _Decoder, used to export its stackmap as _Decoder's
|
||||
func _Decoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *_Stack, fv uint64) error {
|
||||
func _Decoder_Shadow(s string, i int, vp unsafe.Pointer, sb *_Stack, fv uint64) (int, error) {
|
||||
// align to assembler_amd64.go: _FP_offs
|
||||
var stacks [_FP_offs]byte
|
||||
runtime.KeepAlive(stacks)
|
||||
|
||||
// must keep rb, vp and sb noticeable to GC
|
||||
// must keep sb noticeable to GC
|
||||
runtime.KeepAlive(sb)
|
||||
runtime.KeepAlive(rb)
|
||||
runtime.KeepAlive(vp)
|
||||
return 0, errCallShadow
|
||||
}
|
||||
|
||||
return errCallShadow
|
||||
//go:nosplit
|
||||
// Faker func of _Decoder_Generic, used to export its stackmap
|
||||
func _Decoder_Generic_Shadow(sb *_Stack) {
|
||||
// align to generic_amd64.go: _VD_offs
|
||||
var stacks [_VD_offs]byte
|
||||
runtime.KeepAlive(stacks)
|
||||
|
||||
// must keep sb noticeable to GC
|
||||
runtime.KeepAlive(sb)
|
||||
}
|
||||
|
||||
func newStack() *_Stack {
|
||||
|
|
@ -86,6 +94,7 @@ func newStack() *_Stack {
|
|||
}
|
||||
|
||||
func freeStack(p *_Stack) {
|
||||
p.sp = 0
|
||||
stackPool.Put(p)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue