Add noescape trick for encoding

This commit is contained in:
Masaaki Goshima 2020-05-03 22:19:55 +09:00
parent 6602d2d38c
commit 7eba678cef
1 changed files with 11 additions and 6 deletions

View File

@ -34,14 +34,14 @@ type opcodeSet struct {
code *opcode code *opcode
} }
func (m *opcodeMap) get(k *rtype) *opcodeSet { func (m *opcodeMap) get(k uintptr) *opcodeSet {
if v, ok := m.Load(k); ok { if v, ok := m.Load(k); ok {
return v.(*opcodeSet) return v.(*opcodeSet)
} }
return nil return nil
} }
func (m *opcodeMap) set(k *rtype, op *opcodeSet) { func (m *opcodeMap) set(k uintptr, op *opcodeSet) {
m.Store(k, op) m.Store(k, op)
} }
@ -140,7 +140,8 @@ func (e *Encoder) encode(v interface{}) error {
if typ.Kind() == reflect.Ptr { if typ.Kind() == reflect.Ptr {
typ = typ.Elem() typ = typ.Elem()
} }
if codeSet := cachedOpcode.get(typ); codeSet != nil { typeptr := uintptr(unsafe.Pointer(typ))
if codeSet := cachedOpcode.get(typeptr); codeSet != nil {
var code *opcode var code *opcode
if e.enabledIndent { if e.enabledIndent {
code = codeSet.codeIndent code = codeSet.codeIndent
@ -154,16 +155,20 @@ func (e *Encoder) encode(v interface{}) error {
} }
return nil return nil
} }
codeIndent, err := e.compile(typ, true)
// to noescape trick for header.typ ( reflect.*rtype )
copiedType := (*rtype)(unsafe.Pointer(typeptr))
codeIndent, err := e.compile(copiedType, true)
if err != nil { if err != nil {
return err return err
} }
code, err := e.compile(typ, false) code, err := e.compile(copiedType, false)
if err != nil { if err != nil {
return err return err
} }
codeSet := &opcodeSet{codeIndent: codeIndent, code: code} codeSet := &opcodeSet{codeIndent: codeIndent, code: code}
cachedOpcode.set(typ, codeSet) cachedOpcode.set(typeptr, codeSet)
p := uintptr(header.ptr) p := uintptr(header.ptr)
code.ptr = p code.ptr = p
if e.enabledIndent { if e.enabledIndent {