2
0
Fork 0
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:
Yi Duan 2021-11-15 14:41:04 +08:00 committed by GitHub
parent 0f66ab7211
commit ba4c2d2e55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 15 deletions

View file

@ -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

View file

@ -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)
}
}
}

View file

@ -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)
}
}
}

View file

@ -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)
}