Use encodeRuntimeContext.ptrs instead of opcode.ptr

This commit is contained in:
Masaaki Goshima 2020-08-30 23:58:58 +09:00
parent cb194687a0
commit 70f8f01ef3
4 changed files with 1211 additions and 949 deletions

View File

@ -162,19 +162,17 @@ func (e *Encoder) encode(v interface{}) error {
} else { } else {
code = codeSet.code.Get().(*opcode) code = codeSet.code.Get().(*opcode)
} }
ctx := codeSet.ctx.Get().(encodeRuntimeContext) ctx := codeSet.ctx.Get().(*encodeRuntimeContext)
p := uintptr(header.ptr) p := uintptr(header.ptr)
ctx.init(p) ctx.init(p)
code.ptr = p err := e.run(ctx, code)
if err := e.run(ctx, code); err != nil {
return err
}
if e.enabledIndent { if e.enabledIndent {
codeSet.codeIndent.Put(code) codeSet.codeIndent.Put(code)
} else { } else {
codeSet.code.Put(code) codeSet.code.Put(code)
} }
return nil codeSet.ctx.Put(ctx)
return err
} }
// noescape trick for header.typ ( reflect.*rtype ) // noescape trick for header.typ ( reflect.*rtype )
@ -210,20 +208,28 @@ func (e *Encoder) encode(v interface{}) error {
}, },
ctx: sync.Pool{ ctx: sync.Pool{
New: func() interface{} { New: func() interface{} {
return make(encodeRuntimeContext, codeLength) return &encodeRuntimeContext{
ptrs: make([]uintptr, codeLength),
seenPtr: map[uintptr]struct{}{},
}
}, },
}, },
} }
cachedOpcode.set(typeptr, codeSet) cachedOpcode.set(typeptr, codeSet)
p := uintptr(header.ptr) p := uintptr(header.ptr)
ctx := codeSet.ctx.Get().(encodeRuntimeContext) ctx := codeSet.ctx.Get().(*encodeRuntimeContext)
ctx.init(p) ctx.init(p)
if e.enabledIndent { if e.enabledIndent {
codeIndent.ptr = p err := e.run(ctx, codeIndent)
return e.run(ctx, codeIndent) codeSet.ctx.Put(ctx)
return err
} }
code.ptr = p if err := e.run(ctx, code); err != nil {
return e.run(ctx, code) codeSet.ctx.Put(ctx)
return err
}
codeSet.ctx.Put(ctx)
return err
} }
func (e *Encoder) encodeInt(v int) { func (e *Encoder) encodeInt(v int) {

View File

@ -58,13 +58,16 @@ func (c *encodeCompileContext) decOpcodeIndex() {
} }
} }
type encodeRuntimeContext []uintptr type encodeRuntimeContext struct {
ptrs []uintptr
seenPtr map[uintptr]struct{}
}
func (c *encodeRuntimeContext) init(p uintptr) { func (c *encodeRuntimeContext) init(p uintptr) {
(*c)[0] = p c.ptrs[0] = p
} }
func (c *encodeRuntimeContext) ptr() *uintptr { func (c *encodeRuntimeContext) ptr() uintptr {
header := (*reflect.SliceHeader)(unsafe.Pointer(c)) header := (*reflect.SliceHeader)(unsafe.Pointer(&c.ptrs))
return (*uintptr)(unsafe.Pointer(&header.Data)) return header.Data
} }

View File

@ -16,7 +16,6 @@ type opcodeHeader struct {
op opType op opType
typ *rtype typ *rtype
idx int idx int
ptr uintptr
indent int indent int
next *opcode next *opcode
} }
@ -26,7 +25,6 @@ func (h *opcodeHeader) copy(codeMap map[uintptr]*opcode) *opcodeHeader {
op: h.op, op: h.op,
typ: h.typ, typ: h.typ,
idx: h.idx, idx: h.idx,
ptr: h.ptr,
indent: h.indent, indent: h.indent,
next: h.next.copy(codeMap), next: h.next.copy(codeMap),
} }
@ -616,7 +614,6 @@ func newRecursiveCode(recursive *recursiveCode) *opcode {
code := copyOpcode(recursive.jmp.code) code := copyOpcode(recursive.jmp.code)
head := (*structFieldCode)(unsafe.Pointer(code)) head := (*structFieldCode)(unsafe.Pointer(code))
head.end.next = newEndOp(&encodeCompileContext{}) head.end.next = newEndOp(&encodeCompileContext{})
code.ptr = recursive.ptr
code.op = code.op.ptrHeadToHead() code.op = code.op.ptrHeadToHead()
return code return code

File diff suppressed because it is too large Load Diff