forked from mirror/go-json
Merge pull request #368 from orisano/fix/#331
Improve performance on linkRecursiveCode - cache linked recursive codes for compile
This commit is contained in:
commit
3fdc55a60a
|
@ -885,29 +885,40 @@ func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Cod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) linkRecursiveCode(ctx *compileContext) {
|
func (c *Compiler) linkRecursiveCode(ctx *compileContext) {
|
||||||
|
recursiveCodes := map[uintptr]*CompiledCode{}
|
||||||
for _, recursive := range *ctx.recursiveCodes {
|
for _, recursive := range *ctx.recursiveCodes {
|
||||||
typeptr := uintptr(unsafe.Pointer(recursive.Type))
|
typeptr := uintptr(unsafe.Pointer(recursive.Type))
|
||||||
codes := ctx.structTypeToCodes[typeptr]
|
codes := ctx.structTypeToCodes[typeptr]
|
||||||
compiled := recursive.Jmp
|
if recursiveCode, ok := recursiveCodes[typeptr]; ok {
|
||||||
compiled.Code = copyOpcode(codes.First())
|
*recursive.Jmp = *recursiveCode
|
||||||
code := compiled.Code
|
continue
|
||||||
code.End.Next = newEndOp(&compileContext{}, recursive.Type)
|
}
|
||||||
code.Op = code.Op.PtrHeadToHead()
|
|
||||||
|
|
||||||
beforeLastCode := code.End
|
code := copyOpcode(codes.First())
|
||||||
lastCode := beforeLastCode.Next
|
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()
|
totalLength := code.TotalLength()
|
||||||
|
|
||||||
|
// Idx, ElemIdx, Length must set after call TotalLength
|
||||||
lastCode.Idx = uint32((totalLength + 1) * uintptrSize)
|
lastCode.Idx = uint32((totalLength + 1) * uintptrSize)
|
||||||
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
||||||
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
||||||
code.End.Next.Op = OpRecursiveEnd
|
|
||||||
|
|
||||||
// extend length to alloc slot for elemIdx + length
|
// extend length to alloc slot for elemIdx + length
|
||||||
curTotalLength := uintptr(recursive.TotalLength()) + 3
|
curTotalLength := uintptr(recursive.TotalLength()) + 3
|
||||||
nextTotalLength := uintptr(totalLength) + 3
|
nextTotalLength := uintptr(totalLength) + 3
|
||||||
|
|
||||||
|
compiled := recursive.Jmp
|
||||||
|
compiled.Code = code
|
||||||
compiled.CurLen = curTotalLength
|
compiled.CurLen = curTotalLength
|
||||||
compiled.NextLen = nextTotalLength
|
compiled.NextLen = nextTotalLength
|
||||||
compiled.Linked = true
|
compiled.Linked = true
|
||||||
|
|
||||||
|
recursiveCodes[typeptr] = compiled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue