Skip to content

Commit

Permalink
Merge pull request #368 from orisano/fix/#331
Browse files Browse the repository at this point in the history
Improve performance on linkRecursiveCode
- cache linked recursive codes for compile
  • Loading branch information
goccy authored May 3, 2022
2 parents 41b2e78 + c07df9a commit 3fdc55a
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions internal/encoder/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
if recursiveCode, ok := recursiveCodes[typeptr]; ok {
*recursive.Jmp = *recursiveCode
continue
}

code := copyOpcode(codes.First())
code.Op = code.Op.PtrHeadToHead()
lastCode := newEndOp(&compileContext{}, recursive.Type)
lastCode.Op = OpRecursiveEnd

beforeLastCode := code.End
lastCode := beforeLastCode.Next
// 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
}
}

0 comments on commit 3fdc55a

Please sign in to comment.