From 0f66ab721157029e48bbee72a06b3cf30bd536b1 Mon Sep 17 00:00:00 2001 From: Yi Duan Date: Tue, 9 Nov 2021 12:47:05 +0800 Subject: [PATCH] fix: add stack memory at _VAR_vp to pass the address of vp while recursing (#129) Co-authored-by: duanyi.aster --- encoder/assembler_amd64.go | 7 +++-- issue_test/issue128_test.go | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 issue_test/issue128_test.go diff --git a/encoder/assembler_amd64.go b/encoder/assembler_amd64.go index ceb910f..a5ef29c 100644 --- a/encoder/assembler_amd64.go +++ b/encoder/assembler_amd64.go @@ -72,7 +72,7 @@ const ( _FP_args = 48 // 48 bytes for passing arguments to this function _FP_fargs = 64 // 64 bytes for passing arguments to other Go functions _FP_saves = 64 // 64 bytes for saving the registers before CALL instructions - _FP_locals = 16 // 16 bytes for local variables + _FP_locals = 24 // 24 bytes for local variables ) const ( @@ -157,6 +157,7 @@ var ( var ( _VAR_sp = jit.Ptr(_SP, _FP_fargs + _FP_saves) _VAR_dn = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8) + _VAR_vp = jit.Ptr(_SP, _FP_fargs + _FP_saves + 16) ) var ( @@ -963,8 +964,8 @@ func (self *_Assembler) _asm_OP_recurse(p *_Instr) { if (p.vf() & rt.F_direct) != 0 { self.Emit("MOVQ", _SP_p, _AX) // MOVQ SP.p, AX } else { - self.Emit("MOVQ", _SP_p, jit.Ptr(_SP, 48)) // MOVQ SP.p, 48(SP) - self.Emit("LEAQ", jit.Ptr(_SP, 48), _AX) // LEAQ 48(SP), AX + self.Emit("MOVQ", _SP_p, _VAR_vp) // MOVQ SP.p, 48(SP) + self.Emit("LEAQ", _VAR_vp, _AX) // LEAQ 48(SP), AX } /* call the encoder */ diff --git a/issue_test/issue128_test.go b/issue_test/issue128_test.go new file mode 100644 index 0000000..96cf78e --- /dev/null +++ b/issue_test/issue128_test.go @@ -0,0 +1,56 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package issue_test + +import ( + `runtime/debug` + `testing` + + `github.com/bytedance/sonic` +) + +//NOTICE: only DEBUG mode can reproduce problem +func TestDebug(t *testing.T) { + debug.SetGCPercent(-1) + data := &Data{ + Details: []*Detail{ + { + Info: Info{}, + }, + }, + } + + body, err := sonic.Marshal(data) + if err != nil { + t.Error(err) + return + } + t.Log(string(body)) +} + +type Detail struct { + Info Info +} + +type Info struct { + A int +} + +type Data struct { + Details []*Detail +} +