From c07df9add625a24d8def6ae0ee606b5149d0ef89 Mon Sep 17 00:00:00 2001 From: Nao Yonashiro Date: Tue, 3 May 2022 04:03:05 +0900 Subject: [PATCH] feat: improve performance on linkRecursiveCode fix #331 --- internal/encoder/compiler.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go index 0eb3d90..1be01aa 100644 --- a/internal/encoder/compiler.go +++ b/internal/encoder/compiler.go @@ -885,29 +885,40 @@ func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Cod } func (c *Compiler) linkRecursiveCode(ctx *compileContext) { + recursiveCodes := map[uintptr]*CompiledCode{} for _, recursive := range *ctx.recursiveCodes { typeptr := uintptr(unsafe.Pointer(recursive.Type)) codes := ctx.structTypeToCodes[typeptr] - compiled := recursive.Jmp - compiled.Code = copyOpcode(codes.First()) - code := compiled.Code - code.End.Next = newEndOp(&compileContext{}, recursive.Type) - code.Op = code.Op.PtrHeadToHead() + if recursiveCode, ok := recursiveCodes[typeptr]; ok { + *recursive.Jmp = *recursiveCode + continue + } - beforeLastCode := code.End - lastCode := beforeLastCode.Next + code := copyOpcode(codes.First()) + code.Op = code.Op.PtrHeadToHead() + lastCode := newEndOp(&compileContext{}, recursive.Type) + lastCode.Op = OpRecursiveEnd + + // OpRecursiveEnd must set before call TotalLength + code.End.Next = lastCode totalLength := code.TotalLength() + + // Idx, ElemIdx, Length must set after call TotalLength lastCode.Idx = uint32((totalLength + 1) * uintptrSize) lastCode.ElemIdx = lastCode.Idx + uintptrSize lastCode.Length = lastCode.Idx + 2*uintptrSize - code.End.Next.Op = OpRecursiveEnd // extend length to alloc slot for elemIdx + length curTotalLength := uintptr(recursive.TotalLength()) + 3 nextTotalLength := uintptr(totalLength) + 3 + + compiled := recursive.Jmp + compiled.Code = code compiled.CurLen = curTotalLength compiled.NextLen = nextTotalLength compiled.Linked = true + + recursiveCodes[typeptr] = compiled } }