diff --git a/decoder/pools.go b/decoder/pools.go index 9dc4574..0806727 100644 --- a/decoder/pools.go +++ b/decoder/pools.go @@ -60,17 +60,35 @@ type _Decoder func( fv uint64, ) (int, error) +var _KeepAlive struct { + s string + i int + vp unsafe.Pointer + sb *_Stack + fv uint64 + ret int + err error + frame [_FP_offs]byte +} + 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(s string, i int, vp unsafe.Pointer, sb *_Stack, fv uint64) (int, error) { +func _Decoder_Shadow(s string, i int, vp unsafe.Pointer, sb *_Stack, fv uint64) (ret int, err error) { // align to assembler_amd64.go: _FP_offs - var stacks [_FP_offs]byte - runtime.KeepAlive(stacks) + var frame [_FP_offs]byte + + // keep all args and stacks alive + _KeepAlive.s = s + _KeepAlive.i = i + _KeepAlive.vp = vp + _KeepAlive.sb = sb + _KeepAlive.fv = fv + _KeepAlive.ret = ret + _KeepAlive.err = err + _KeepAlive.frame = frame - // must keep sb noticeable to GC - runtime.KeepAlive(sb) return 0, errCallShadow } diff --git a/decoder/stubs.go b/decoder/stubs.go index efa160f..f6b4d20 100644 --- a/decoder/stubs.go +++ b/decoder/stubs.go @@ -1,3 +1,4 @@ + /* * Copyright 2021 ByteDance Inc. * diff --git a/encoder/debug.go b/encoder/debug.go index 71ca211..5575239 100644 --- a/encoder/debug.go +++ b/encoder/debug.go @@ -26,7 +26,7 @@ import ( ) var ( - debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" + debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" ) diff --git a/encoder/pools.go b/encoder/pools.go index 0ab6d86..f8ae304 100644 --- a/encoder/pools.go +++ b/encoder/pools.go @@ -18,10 +18,9 @@ package encoder import ( `bytes` - `errors` - `runtime` `sync` `unsafe` + `errors` `github.com/bytedance/sonic/internal/caching` `github.com/bytedance/sonic/internal/rt` @@ -58,24 +57,34 @@ type _Encoder func( fv uint64, ) error +var _KeepAlive struct { + rb *[]byte + vp unsafe.Pointer + sb *_Stack + fv uint64 + err error + frame [_FP_offs]byte +} + var errCallShadow = errors.New("DON'T CALL THIS!") // Faker func of _Encoder, used to export its stackmap as _Encoder's //go:nosplit -func _Encoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *_Stack, fv uint64) error { +func _Encoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *_Stack, fv uint64) (err error) { // align to assembler_amd64.go: _FP_offs - var frames [_FP_offs]byte - runtime.KeepAlive(frames) + var frame [_FP_offs]byte - // must keep sb noticeable to GC - runtime.KeepAlive(sb) - runtime.KeepAlive(rb) - runtime.KeepAlive(vp) + // must keep all args and frames noticeable to GC + _KeepAlive.rb = rb + _KeepAlive.vp = vp + _KeepAlive.sb = sb + _KeepAlive.fv = fv + _KeepAlive.err = err + _KeepAlive.frame = frame return errCallShadow } - func newBytes() []byte { if ret := bytesPool.Get(); ret != nil { return ret.([]byte)