forked from mirror/go-json
Add encodeRuntimeContext
This commit is contained in:
parent
a9e2386e42
commit
cb194687a0
17
encode.go
17
encode.go
|
@ -38,6 +38,7 @@ type opcodeMap struct {
|
||||||
type opcodeSet struct {
|
type opcodeSet struct {
|
||||||
codeIndent sync.Pool
|
codeIndent sync.Pool
|
||||||
code sync.Pool
|
code sync.Pool
|
||||||
|
ctx sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *opcodeMap) get(k uintptr) *opcodeSet {
|
func (m *opcodeMap) get(k uintptr) *opcodeSet {
|
||||||
|
@ -161,9 +162,11 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
} else {
|
} else {
|
||||||
code = codeSet.code.Get().(*opcode)
|
code = codeSet.code.Get().(*opcode)
|
||||||
}
|
}
|
||||||
|
ctx := codeSet.ctx.Get().(encodeRuntimeContext)
|
||||||
p := uintptr(header.ptr)
|
p := uintptr(header.ptr)
|
||||||
|
ctx.init(p)
|
||||||
code.ptr = p
|
code.ptr = p
|
||||||
if err := e.run(code); err != nil {
|
if err := e.run(ctx, code); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
|
@ -193,6 +196,7 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
codeLength := code.length()
|
||||||
codeSet := &opcodeSet{
|
codeSet := &opcodeSet{
|
||||||
codeIndent: sync.Pool{
|
codeIndent: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
|
@ -204,15 +208,22 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
return copyOpcode(code)
|
return copyOpcode(code)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ctx: sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return make(encodeRuntimeContext, codeLength)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cachedOpcode.set(typeptr, codeSet)
|
cachedOpcode.set(typeptr, codeSet)
|
||||||
p := uintptr(header.ptr)
|
p := uintptr(header.ptr)
|
||||||
|
ctx := codeSet.ctx.Get().(encodeRuntimeContext)
|
||||||
|
ctx.init(p)
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
codeIndent.ptr = p
|
codeIndent.ptr = p
|
||||||
return e.run(codeIndent)
|
return e.run(ctx, codeIndent)
|
||||||
}
|
}
|
||||||
code.ptr = p
|
code.ptr = p
|
||||||
return e.run(code)
|
return e.run(ctx, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) encodeInt(v int) {
|
func (e *Encoder) encodeInt(v int) {
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
type encodeCompileContext struct {
|
type encodeCompileContext struct {
|
||||||
typ *rtype
|
typ *rtype
|
||||||
withIndent bool
|
withIndent bool
|
||||||
|
@ -52,3 +57,14 @@ func (c *encodeCompileContext) decOpcodeIndex() {
|
||||||
c.parent.decOpcodeIndex()
|
c.parent.decOpcodeIndex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type encodeRuntimeContext []uintptr
|
||||||
|
|
||||||
|
func (c *encodeRuntimeContext) init(p uintptr) {
|
||||||
|
(*c)[0] = p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeRuntimeContext) ptr() *uintptr {
|
||||||
|
header := (*reflect.SliceHeader)(unsafe.Pointer(c))
|
||||||
|
return (*uintptr)(unsafe.Pointer(&header.Data))
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,24 @@ func (c *opcode) beforeLastCode() *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *opcode) length() int {
|
||||||
|
var idx int
|
||||||
|
for code := c; code.op != opEnd; {
|
||||||
|
idx = code.idx
|
||||||
|
switch code.op.codeType() {
|
||||||
|
case codeArrayElem:
|
||||||
|
code = code.toArrayElemCode().end
|
||||||
|
case codeSliceElem:
|
||||||
|
code = code.toSliceElemCode().end
|
||||||
|
case codeMapKey:
|
||||||
|
code = code.toMapKeyCode().end
|
||||||
|
default:
|
||||||
|
code = code.next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return idx + 1
|
||||||
|
}
|
||||||
|
|
||||||
func (c *opcode) decOpcodeIndex() {
|
func (c *opcode) decOpcodeIndex() {
|
||||||
for code := c; code.op != opEnd; {
|
for code := c; code.op != opEnd; {
|
||||||
code.idx--
|
code.idx--
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *Encoder) run(code *opcode) error {
|
func (e *Encoder) run(ctx encodeRuntimeContext, code *opcode) error {
|
||||||
seenPtr := map[uintptr]struct{}{}
|
seenPtr := map[uintptr]struct{}{}
|
||||||
for {
|
for {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
|
@ -546,7 +546,7 @@ func (e *Encoder) run(code *opcode) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recursive.seenPtr = recursive.ptr
|
recursive.seenPtr = recursive.ptr
|
||||||
if err := e.run(newRecursiveCode(recursive)); err != nil {
|
if err := e.run(nil, newRecursiveCode(recursive)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
code = recursive.next
|
code = recursive.next
|
||||||
|
|
Loading…
Reference in New Issue