mirror of https://github.com/goccy/go-json.git
Fix parallel encoding
This commit is contained in:
parent
c359cc258f
commit
b9bb609c1d
30
encode.go
30
encode.go
|
@ -31,8 +31,8 @@ type opcodeMap struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type opcodeSet struct {
|
type opcodeSet struct {
|
||||||
codeIndent *opcode
|
codeIndent sync.Pool
|
||||||
code *opcode
|
code sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *opcodeMap) get(k uintptr) *opcodeSet {
|
func (m *opcodeMap) get(k uintptr) *opcodeSet {
|
||||||
|
@ -48,6 +48,7 @@ func (m *opcodeMap) set(k uintptr, op *opcodeSet) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
encPool sync.Pool
|
encPool sync.Pool
|
||||||
|
codePool sync.Pool
|
||||||
cachedOpcode opcodeMap
|
cachedOpcode opcodeMap
|
||||||
marshalJSONType reflect.Type
|
marshalJSONType reflect.Type
|
||||||
marshalTextType reflect.Type
|
marshalTextType reflect.Type
|
||||||
|
@ -147,15 +148,20 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
if codeSet := cachedOpcode.get(typeptr); codeSet != nil {
|
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.Get().(*opcode)
|
||||||
} else {
|
} else {
|
||||||
code = codeSet.code
|
code = codeSet.code.Get().(*opcode)
|
||||||
}
|
}
|
||||||
p := uintptr(header.ptr)
|
p := uintptr(header.ptr)
|
||||||
code.ptr = p
|
code.ptr = p
|
||||||
if err := e.run(code); err != nil {
|
if err := e.run(code); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if e.enabledIndent {
|
||||||
|
codeSet.codeIndent.Put(code)
|
||||||
|
} else {
|
||||||
|
codeSet.code.Put(code)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +176,25 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
codeSet := &opcodeSet{codeIndent: codeIndent, code: code}
|
codeSet := &opcodeSet{
|
||||||
|
codeIndent: sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return copyOpcode(codeIndent)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
code: sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return copyOpcode(code)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
cachedOpcode.set(typeptr, codeSet)
|
cachedOpcode.set(typeptr, codeSet)
|
||||||
p := uintptr(header.ptr)
|
p := uintptr(header.ptr)
|
||||||
code.ptr = p
|
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
|
codeIndent.ptr = p
|
||||||
return e.run(codeIndent)
|
return e.run(codeIndent)
|
||||||
}
|
}
|
||||||
|
code.ptr = p
|
||||||
return e.run(code)
|
return e.run(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
388
encode_opcode.go
388
encode_opcode.go
|
@ -731,6 +731,11 @@ func (t opType) String() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func copyOpcode(code *opcode) *opcode {
|
||||||
|
codeMap := map[uintptr]*opcode{}
|
||||||
|
return code.copy(codeMap)
|
||||||
|
}
|
||||||
|
|
||||||
type opcodeHeader struct {
|
type opcodeHeader struct {
|
||||||
op opType
|
op opType
|
||||||
typ *rtype
|
typ *rtype
|
||||||
|
@ -739,6 +744,16 @@ type opcodeHeader struct {
|
||||||
next *opcode
|
next *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *opcodeHeader) copy(codeMap map[uintptr]*opcode) *opcodeHeader {
|
||||||
|
return &opcodeHeader{
|
||||||
|
op: h.op,
|
||||||
|
typ: h.typ,
|
||||||
|
ptr: h.ptr,
|
||||||
|
indent: h.indent,
|
||||||
|
next: h.next.copy(codeMap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type opcode struct {
|
type opcode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
}
|
}
|
||||||
|
@ -780,6 +795,220 @@ func (c *opcode) beforeLastCode() *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
var code *opcode
|
||||||
|
switch c.op {
|
||||||
|
case opArrayHead, opArrayHeadIndent:
|
||||||
|
code = c.toArrayHeaderCode().copy(codeMap)
|
||||||
|
case opArrayElem, opArrayElemIndent:
|
||||||
|
code = c.toArrayElemCode().copy(codeMap)
|
||||||
|
case opSliceHead, opSliceHeadIndent:
|
||||||
|
code = c.toSliceHeaderCode().copy(codeMap)
|
||||||
|
case opSliceElem, opSliceElemIndent:
|
||||||
|
code = c.toSliceElemCode().copy(codeMap)
|
||||||
|
case opMapHead, opMapHeadLoad, opMapHeadIndent, opMapHeadLoadIndent:
|
||||||
|
code = c.toMapHeadCode().copy(codeMap)
|
||||||
|
case opMapKey, opMapKeyIndent:
|
||||||
|
code = c.toMapKeyCode().copy(codeMap)
|
||||||
|
case opMapValue, opMapValueIndent:
|
||||||
|
code = c.toMapValueCode().copy(codeMap)
|
||||||
|
case opStructFieldHead,
|
||||||
|
opStructFieldHeadInt,
|
||||||
|
opStructFieldHeadInt8,
|
||||||
|
opStructFieldHeadInt16,
|
||||||
|
opStructFieldHeadInt32,
|
||||||
|
opStructFieldHeadInt64,
|
||||||
|
opStructFieldHeadUint,
|
||||||
|
opStructFieldHeadUint8,
|
||||||
|
opStructFieldHeadUint16,
|
||||||
|
opStructFieldHeadUint32,
|
||||||
|
opStructFieldHeadUint64,
|
||||||
|
opStructFieldHeadFloat32,
|
||||||
|
opStructFieldHeadFloat64,
|
||||||
|
opStructFieldHeadString,
|
||||||
|
opStructFieldHeadBool,
|
||||||
|
opStructFieldHeadIndent,
|
||||||
|
opStructFieldHeadIntIndent,
|
||||||
|
opStructFieldHeadInt8Indent,
|
||||||
|
opStructFieldHeadInt16Indent,
|
||||||
|
opStructFieldHeadInt32Indent,
|
||||||
|
opStructFieldHeadInt64Indent,
|
||||||
|
opStructFieldHeadUintIndent,
|
||||||
|
opStructFieldHeadUint8Indent,
|
||||||
|
opStructFieldHeadUint16Indent,
|
||||||
|
opStructFieldHeadUint32Indent,
|
||||||
|
opStructFieldHeadUint64Indent,
|
||||||
|
opStructFieldHeadFloat32Indent,
|
||||||
|
opStructFieldHeadFloat64Indent,
|
||||||
|
opStructFieldHeadStringIndent,
|
||||||
|
opStructFieldHeadBoolIndent,
|
||||||
|
opStructFieldHeadOmitEmpty,
|
||||||
|
opStructFieldHeadIntOmitEmpty,
|
||||||
|
opStructFieldHeadInt8OmitEmpty,
|
||||||
|
opStructFieldHeadInt16OmitEmpty,
|
||||||
|
opStructFieldHeadInt32OmitEmpty,
|
||||||
|
opStructFieldHeadInt64OmitEmpty,
|
||||||
|
opStructFieldHeadUintOmitEmpty,
|
||||||
|
opStructFieldHeadUint8OmitEmpty,
|
||||||
|
opStructFieldHeadUint16OmitEmpty,
|
||||||
|
opStructFieldHeadUint32OmitEmpty,
|
||||||
|
opStructFieldHeadUint64OmitEmpty,
|
||||||
|
opStructFieldHeadFloat32OmitEmpty,
|
||||||
|
opStructFieldHeadFloat64OmitEmpty,
|
||||||
|
opStructFieldHeadStringOmitEmpty,
|
||||||
|
opStructFieldHeadBoolOmitEmpty,
|
||||||
|
opStructFieldHeadOmitEmptyIndent,
|
||||||
|
opStructFieldHeadIntOmitEmptyIndent,
|
||||||
|
opStructFieldHeadInt8OmitEmptyIndent,
|
||||||
|
opStructFieldHeadInt16OmitEmptyIndent,
|
||||||
|
opStructFieldHeadInt32OmitEmptyIndent,
|
||||||
|
opStructFieldHeadInt64OmitEmptyIndent,
|
||||||
|
opStructFieldHeadUintOmitEmptyIndent,
|
||||||
|
opStructFieldHeadUint8OmitEmptyIndent,
|
||||||
|
opStructFieldHeadUint16OmitEmptyIndent,
|
||||||
|
opStructFieldHeadUint32OmitEmptyIndent,
|
||||||
|
opStructFieldHeadUint64OmitEmptyIndent,
|
||||||
|
opStructFieldHeadFloat32OmitEmptyIndent,
|
||||||
|
opStructFieldHeadFloat64OmitEmptyIndent,
|
||||||
|
opStructFieldHeadStringOmitEmptyIndent,
|
||||||
|
opStructFieldHeadBoolOmitEmptyIndent,
|
||||||
|
opStructFieldPtrHead,
|
||||||
|
opStructFieldPtrHeadInt,
|
||||||
|
opStructFieldPtrHeadInt8,
|
||||||
|
opStructFieldPtrHeadInt16,
|
||||||
|
opStructFieldPtrHeadInt32,
|
||||||
|
opStructFieldPtrHeadInt64,
|
||||||
|
opStructFieldPtrHeadUint,
|
||||||
|
opStructFieldPtrHeadUint8,
|
||||||
|
opStructFieldPtrHeadUint16,
|
||||||
|
opStructFieldPtrHeadUint32,
|
||||||
|
opStructFieldPtrHeadUint64,
|
||||||
|
opStructFieldPtrHeadFloat32,
|
||||||
|
opStructFieldPtrHeadFloat64,
|
||||||
|
opStructFieldPtrHeadString,
|
||||||
|
opStructFieldPtrHeadBool,
|
||||||
|
opStructFieldPtrHeadIndent,
|
||||||
|
opStructFieldPtrHeadIntIndent,
|
||||||
|
opStructFieldPtrHeadInt8Indent,
|
||||||
|
opStructFieldPtrHeadInt16Indent,
|
||||||
|
opStructFieldPtrHeadInt32Indent,
|
||||||
|
opStructFieldPtrHeadInt64Indent,
|
||||||
|
opStructFieldPtrHeadUintIndent,
|
||||||
|
opStructFieldPtrHeadUint8Indent,
|
||||||
|
opStructFieldPtrHeadUint16Indent,
|
||||||
|
opStructFieldPtrHeadUint32Indent,
|
||||||
|
opStructFieldPtrHeadUint64Indent,
|
||||||
|
opStructFieldPtrHeadFloat32Indent,
|
||||||
|
opStructFieldPtrHeadFloat64Indent,
|
||||||
|
opStructFieldPtrHeadStringIndent,
|
||||||
|
opStructFieldPtrHeadBoolIndent,
|
||||||
|
opStructFieldPtrHeadOmitEmpty,
|
||||||
|
opStructFieldPtrHeadIntOmitEmpty,
|
||||||
|
opStructFieldPtrHeadInt8OmitEmpty,
|
||||||
|
opStructFieldPtrHeadInt16OmitEmpty,
|
||||||
|
opStructFieldPtrHeadInt32OmitEmpty,
|
||||||
|
opStructFieldPtrHeadInt64OmitEmpty,
|
||||||
|
opStructFieldPtrHeadUintOmitEmpty,
|
||||||
|
opStructFieldPtrHeadUint8OmitEmpty,
|
||||||
|
opStructFieldPtrHeadUint16OmitEmpty,
|
||||||
|
opStructFieldPtrHeadUint32OmitEmpty,
|
||||||
|
opStructFieldPtrHeadUint64OmitEmpty,
|
||||||
|
opStructFieldPtrHeadFloat32OmitEmpty,
|
||||||
|
opStructFieldPtrHeadFloat64OmitEmpty,
|
||||||
|
opStructFieldPtrHeadStringOmitEmpty,
|
||||||
|
opStructFieldPtrHeadBoolOmitEmpty,
|
||||||
|
opStructFieldPtrHeadOmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadIntOmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadInt8OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadInt16OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadInt32OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadInt64OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadUintOmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadUint8OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadUint16OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadUint32OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadUint64OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadFloat32OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadFloat64OmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadStringOmitEmptyIndent,
|
||||||
|
opStructFieldPtrHeadBoolOmitEmptyIndent,
|
||||||
|
opStructField,
|
||||||
|
opStructFieldInt,
|
||||||
|
opStructFieldInt8,
|
||||||
|
opStructFieldInt16,
|
||||||
|
opStructFieldInt32,
|
||||||
|
opStructFieldInt64,
|
||||||
|
opStructFieldUint,
|
||||||
|
opStructFieldUint8,
|
||||||
|
opStructFieldUint16,
|
||||||
|
opStructFieldUint32,
|
||||||
|
opStructFieldUint64,
|
||||||
|
opStructFieldFloat32,
|
||||||
|
opStructFieldFloat64,
|
||||||
|
opStructFieldString,
|
||||||
|
opStructFieldBool,
|
||||||
|
opStructFieldIndent,
|
||||||
|
opStructFieldIntIndent,
|
||||||
|
opStructFieldInt8Indent,
|
||||||
|
opStructFieldInt16Indent,
|
||||||
|
opStructFieldInt32Indent,
|
||||||
|
opStructFieldInt64Indent,
|
||||||
|
opStructFieldUintIndent,
|
||||||
|
opStructFieldUint8Indent,
|
||||||
|
opStructFieldUint16Indent,
|
||||||
|
opStructFieldUint32Indent,
|
||||||
|
opStructFieldUint64Indent,
|
||||||
|
opStructFieldFloat32Indent,
|
||||||
|
opStructFieldFloat64Indent,
|
||||||
|
opStructFieldStringIndent,
|
||||||
|
opStructFieldBoolIndent,
|
||||||
|
opStructFieldOmitEmpty,
|
||||||
|
opStructFieldIntOmitEmpty,
|
||||||
|
opStructFieldInt8OmitEmpty,
|
||||||
|
opStructFieldInt16OmitEmpty,
|
||||||
|
opStructFieldInt32OmitEmpty,
|
||||||
|
opStructFieldInt64OmitEmpty,
|
||||||
|
opStructFieldUintOmitEmpty,
|
||||||
|
opStructFieldUint8OmitEmpty,
|
||||||
|
opStructFieldUint16OmitEmpty,
|
||||||
|
opStructFieldUint32OmitEmpty,
|
||||||
|
opStructFieldUint64OmitEmpty,
|
||||||
|
opStructFieldFloat32OmitEmpty,
|
||||||
|
opStructFieldFloat64OmitEmpty,
|
||||||
|
opStructFieldStringOmitEmpty,
|
||||||
|
opStructFieldBoolOmitEmpty,
|
||||||
|
opStructFieldOmitEmptyIndent,
|
||||||
|
opStructFieldIntOmitEmptyIndent,
|
||||||
|
opStructFieldInt8OmitEmptyIndent,
|
||||||
|
opStructFieldInt16OmitEmptyIndent,
|
||||||
|
opStructFieldInt32OmitEmptyIndent,
|
||||||
|
opStructFieldInt64OmitEmptyIndent,
|
||||||
|
opStructFieldUintOmitEmptyIndent,
|
||||||
|
opStructFieldUint8OmitEmptyIndent,
|
||||||
|
opStructFieldUint16OmitEmptyIndent,
|
||||||
|
opStructFieldUint32OmitEmptyIndent,
|
||||||
|
opStructFieldUint64OmitEmptyIndent,
|
||||||
|
opStructFieldFloat32OmitEmptyIndent,
|
||||||
|
opStructFieldFloat64OmitEmptyIndent,
|
||||||
|
opStructFieldStringOmitEmptyIndent,
|
||||||
|
opStructFieldBoolOmitEmptyIndent:
|
||||||
|
code = c.toStructFieldCode().copy(codeMap)
|
||||||
|
default:
|
||||||
|
code = &opcode{}
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
code.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
func (c *opcode) dump() string {
|
func (c *opcode) dump() string {
|
||||||
codes := []string{}
|
codes := []string{}
|
||||||
for code := c; code.op != opEnd; {
|
for code := c; code.op != opEnd; {
|
||||||
|
@ -846,6 +1075,24 @@ func newSliceHeaderCode(indent int) *sliceHeaderCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *sliceHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
header := &sliceHeaderCode{}
|
||||||
|
code := (*opcode)(unsafe.Pointer(header))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
header.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
header.elem = (*sliceElemCode)(unsafe.Pointer(c.elem.copy(codeMap)))
|
||||||
|
header.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type sliceElemCode struct {
|
type sliceElemCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
idx uintptr
|
idx uintptr
|
||||||
|
@ -861,6 +1108,28 @@ func (c *sliceElemCode) set(header *reflect.SliceHeader) {
|
||||||
c.data = header.Data
|
c.data = header.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *sliceElemCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
elem := &sliceElemCode{
|
||||||
|
idx: c.idx,
|
||||||
|
len: c.len,
|
||||||
|
size: c.size,
|
||||||
|
data: c.data,
|
||||||
|
}
|
||||||
|
code := (*opcode)(unsafe.Pointer(elem))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
elem.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
elem.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type arrayHeaderCode struct {
|
type arrayHeaderCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
len uintptr
|
len uintptr
|
||||||
|
@ -878,6 +1147,25 @@ func newArrayHeaderCode(indent, alen int) *arrayHeaderCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *arrayHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
header := &arrayHeaderCode{}
|
||||||
|
code := (*opcode)(unsafe.Pointer(header))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
header.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
header.len = c.len
|
||||||
|
header.elem = (*arrayElemCode)(unsafe.Pointer(c.elem.copy(codeMap)))
|
||||||
|
header.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type arrayElemCode struct {
|
type arrayElemCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
idx uintptr
|
idx uintptr
|
||||||
|
@ -886,6 +1174,27 @@ type arrayElemCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *arrayElemCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
elem := &arrayElemCode{
|
||||||
|
idx: c.idx,
|
||||||
|
len: c.len,
|
||||||
|
size: c.size,
|
||||||
|
}
|
||||||
|
code := (*opcode)(unsafe.Pointer(elem))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
elem.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
elem.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type structFieldCode struct {
|
type structFieldCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
key []byte
|
key []byte
|
||||||
|
@ -894,6 +1203,27 @@ type structFieldCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *structFieldCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
field := &structFieldCode{
|
||||||
|
key: c.key,
|
||||||
|
offset: c.offset,
|
||||||
|
}
|
||||||
|
code := (*opcode)(unsafe.Pointer(field))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
field.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
field.nextField = c.nextField.copy(codeMap)
|
||||||
|
field.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type mapHeaderCode struct {
|
type mapHeaderCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
key *mapKeyCode
|
key *mapKeyCode
|
||||||
|
@ -901,6 +1231,25 @@ type mapHeaderCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *mapHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
header := &mapHeaderCode{}
|
||||||
|
code := (*opcode)(unsafe.Pointer(header))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
header.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
header.key = (*mapKeyCode)(unsafe.Pointer(c.key.copy(codeMap)))
|
||||||
|
header.value = (*mapValueCode)(unsafe.Pointer(c.value.copy(codeMap)))
|
||||||
|
header.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
type mapKeyCode struct {
|
type mapKeyCode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
idx int
|
idx int
|
||||||
|
@ -909,6 +1258,27 @@ type mapKeyCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *mapKeyCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
key := &mapKeyCode{
|
||||||
|
idx: c.idx,
|
||||||
|
len: c.len,
|
||||||
|
iter: c.iter,
|
||||||
|
}
|
||||||
|
code := (*opcode)(unsafe.Pointer(key))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
key.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
key.end = c.end.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
func (c *mapKeyCode) set(len int, iter unsafe.Pointer) {
|
func (c *mapKeyCode) set(len int, iter unsafe.Pointer) {
|
||||||
c.idx = 0
|
c.idx = 0
|
||||||
c.len = len
|
c.len = len
|
||||||
|
@ -920,6 +1290,24 @@ type mapValueCode struct {
|
||||||
iter unsafe.Pointer
|
iter unsafe.Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *mapValueCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
addr := uintptr(unsafe.Pointer(c))
|
||||||
|
if code, exists := codeMap[addr]; exists {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
value := &mapValueCode{
|
||||||
|
iter: c.iter,
|
||||||
|
}
|
||||||
|
code := (*opcode)(unsafe.Pointer(value))
|
||||||
|
codeMap[addr] = code
|
||||||
|
|
||||||
|
value.opcodeHeader = c.opcodeHeader.copy(codeMap)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
func (c *mapValueCode) set(iter unsafe.Pointer) {
|
func (c *mapValueCode) set(iter unsafe.Pointer) {
|
||||||
c.iter = iter
|
c.iter = iter
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue