mirror of https://github.com/goccy/go-json.git
Add UnmarshalNoEscape
This commit is contained in:
parent
101def2916
commit
24447ce7e9
|
@ -131,3 +131,13 @@ func Benchmark_Decode_gojson(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Benchmark_Decode_gojson_noescape(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
var v SmallPayload
|
||||||
|
if err := gojson.UnmarshalNoEscape(fixture, &v); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
decode.go
14
decode.go
|
@ -53,8 +53,7 @@ func (d *Decoder) Buffered() io.Reader {
|
||||||
return d.r
|
return d.r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeForUnmarshal(src []byte, v interface{}) error {
|
func (d *Decoder) decode(src []byte, header *interfaceHeader) error {
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
|
||||||
typ := header.typ
|
typ := header.typ
|
||||||
if typ.Kind() != reflect.Ptr {
|
if typ.Kind() != reflect.Ptr {
|
||||||
return ErrDecodePointer
|
return ErrDecodePointer
|
||||||
|
@ -82,6 +81,17 @@ func (d *Decoder) decodeForUnmarshal(src []byte, v interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) decodeForUnmarshal(src []byte, v interface{}) error {
|
||||||
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
|
header.typ.escape()
|
||||||
|
return d.decode(src, header)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) decodeForUnmarshalNoEscape(src []byte, v interface{}) error {
|
||||||
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
|
return d.decode(src, header)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Decoder) Decode(v interface{}) error {
|
func (d *Decoder) Decode(v interface{}) error {
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
typ := header.typ
|
typ := header.typ
|
||||||
|
|
7
json.go
7
json.go
|
@ -20,3 +20,10 @@ func Unmarshal(data []byte, v interface{}) error {
|
||||||
var dec Decoder
|
var dec Decoder
|
||||||
return dec.decodeForUnmarshal(src, v)
|
return dec.decodeForUnmarshal(src, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UnmarshalNoEscape(data []byte, v interface{}) error {
|
||||||
|
src := make([]byte, len(data))
|
||||||
|
copy(src, data)
|
||||||
|
var dec Decoder
|
||||||
|
return dec.decodeForUnmarshalNoEscape(src, v)
|
||||||
|
}
|
||||||
|
|
28
rtype.go
28
rtype.go
|
@ -9,6 +9,7 @@ import (
|
||||||
type rtype struct{}
|
type rtype struct{}
|
||||||
|
|
||||||
//go:linkname rtype_Align reflect.(*rtype).Align
|
//go:linkname rtype_Align reflect.(*rtype).Align
|
||||||
|
//go:noescape
|
||||||
func rtype_Align(*rtype) int
|
func rtype_Align(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) Align() int {
|
func (t *rtype) Align() int {
|
||||||
|
@ -16,6 +17,7 @@ func (t *rtype) Align() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_FieldAlign reflect.(*rtype).FieldAlign
|
//go:linkname rtype_FieldAlign reflect.(*rtype).FieldAlign
|
||||||
|
//go:noescape
|
||||||
func rtype_FieldAlign(*rtype) int
|
func rtype_FieldAlign(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) FieldAlign() int {
|
func (t *rtype) FieldAlign() int {
|
||||||
|
@ -23,6 +25,7 @@ func (t *rtype) FieldAlign() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Method reflect.(*rtype).Method
|
//go:linkname rtype_Method reflect.(*rtype).Method
|
||||||
|
//go:noescape
|
||||||
func rtype_Method(*rtype, int) reflect.Method
|
func rtype_Method(*rtype, int) reflect.Method
|
||||||
|
|
||||||
func (t *rtype) Method(a0 int) reflect.Method {
|
func (t *rtype) Method(a0 int) reflect.Method {
|
||||||
|
@ -30,6 +33,7 @@ func (t *rtype) Method(a0 int) reflect.Method {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_MethodByName reflect.(*rtype).MethodByName
|
//go:linkname rtype_MethodByName reflect.(*rtype).MethodByName
|
||||||
|
//go:noescape
|
||||||
func rtype_MethodByName(*rtype, string) (reflect.Method, bool)
|
func rtype_MethodByName(*rtype, string) (reflect.Method, bool)
|
||||||
|
|
||||||
func (t *rtype) MethodByName(a0 string) (reflect.Method, bool) {
|
func (t *rtype) MethodByName(a0 string) (reflect.Method, bool) {
|
||||||
|
@ -37,6 +41,7 @@ func (t *rtype) MethodByName(a0 string) (reflect.Method, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod
|
//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod
|
||||||
|
//go:noescape
|
||||||
func rtype_NumMethod(*rtype) int
|
func rtype_NumMethod(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) NumMethod() int {
|
func (t *rtype) NumMethod() int {
|
||||||
|
@ -52,6 +57,7 @@ func (t *rtype) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_PkgPath reflect.(*rtype).PkgPath
|
//go:linkname rtype_PkgPath reflect.(*rtype).PkgPath
|
||||||
|
//go:noescape
|
||||||
func rtype_PkgPath(*rtype) string
|
func rtype_PkgPath(*rtype) string
|
||||||
|
|
||||||
func (t *rtype) PkgPath() string {
|
func (t *rtype) PkgPath() string {
|
||||||
|
@ -83,6 +89,7 @@ func (t *rtype) Kind() reflect.Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Implements reflect.(*rtype).Implements
|
//go:linkname rtype_Implements reflect.(*rtype).Implements
|
||||||
|
//go:noescape
|
||||||
func rtype_Implements(*rtype, reflect.Type) bool
|
func rtype_Implements(*rtype, reflect.Type) bool
|
||||||
|
|
||||||
func (t *rtype) Implements(u reflect.Type) bool {
|
func (t *rtype) Implements(u reflect.Type) bool {
|
||||||
|
@ -90,6 +97,7 @@ func (t *rtype) Implements(u reflect.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_AssignableTo reflect.(*rtype).AssignableTo
|
//go:linkname rtype_AssignableTo reflect.(*rtype).AssignableTo
|
||||||
|
//go:noescape
|
||||||
func rtype_AssignableTo(*rtype, reflect.Type) bool
|
func rtype_AssignableTo(*rtype, reflect.Type) bool
|
||||||
|
|
||||||
func (t *rtype) AssignableTo(u reflect.Type) bool {
|
func (t *rtype) AssignableTo(u reflect.Type) bool {
|
||||||
|
@ -97,6 +105,7 @@ func (t *rtype) AssignableTo(u reflect.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_ConvertibleTo reflect.(*rtype).ConvertibleTo
|
//go:linkname rtype_ConvertibleTo reflect.(*rtype).ConvertibleTo
|
||||||
|
//go:noescape
|
||||||
func rtype_ConvertibleTo(*rtype, reflect.Type) bool
|
func rtype_ConvertibleTo(*rtype, reflect.Type) bool
|
||||||
|
|
||||||
func (t *rtype) ConvertibleTo(u reflect.Type) bool {
|
func (t *rtype) ConvertibleTo(u reflect.Type) bool {
|
||||||
|
@ -104,6 +113,7 @@ func (t *rtype) ConvertibleTo(u reflect.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Comparable reflect.(*rtype).Comparable
|
//go:linkname rtype_Comparable reflect.(*rtype).Comparable
|
||||||
|
//go:noescape
|
||||||
func rtype_Comparable(*rtype) bool
|
func rtype_Comparable(*rtype) bool
|
||||||
|
|
||||||
func (t *rtype) Comparable() bool {
|
func (t *rtype) Comparable() bool {
|
||||||
|
@ -111,6 +121,7 @@ func (t *rtype) Comparable() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Bits reflect.(*rtype).Bits
|
//go:linkname rtype_Bits reflect.(*rtype).Bits
|
||||||
|
//go:noescape
|
||||||
func rtype_Bits(*rtype) int
|
func rtype_Bits(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) Bits() int {
|
func (t *rtype) Bits() int {
|
||||||
|
@ -118,6 +129,7 @@ func (t *rtype) Bits() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_ChanDir reflect.(*rtype).ChanDir
|
//go:linkname rtype_ChanDir reflect.(*rtype).ChanDir
|
||||||
|
//go:noescape
|
||||||
func rtype_ChanDir(*rtype) reflect.ChanDir
|
func rtype_ChanDir(*rtype) reflect.ChanDir
|
||||||
|
|
||||||
func (t *rtype) ChanDir() reflect.ChanDir {
|
func (t *rtype) ChanDir() reflect.ChanDir {
|
||||||
|
@ -125,6 +137,7 @@ func (t *rtype) ChanDir() reflect.ChanDir {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_IsVariadic reflect.(*rtype).IsVariadic
|
//go:linkname rtype_IsVariadic reflect.(*rtype).IsVariadic
|
||||||
|
//go:noescape
|
||||||
func rtype_IsVariadic(*rtype) bool
|
func rtype_IsVariadic(*rtype) bool
|
||||||
|
|
||||||
func (t *rtype) IsVariadic() bool {
|
func (t *rtype) IsVariadic() bool {
|
||||||
|
@ -148,6 +161,7 @@ func (t *rtype) Field(i int) reflect.StructField {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_FieldByIndex reflect.(*rtype).FieldByIndex
|
//go:linkname rtype_FieldByIndex reflect.(*rtype).FieldByIndex
|
||||||
|
//go:noescape
|
||||||
func rtype_FieldByIndex(*rtype, []int) reflect.StructField
|
func rtype_FieldByIndex(*rtype, []int) reflect.StructField
|
||||||
|
|
||||||
func (t *rtype) FieldByIndex(index []int) reflect.StructField {
|
func (t *rtype) FieldByIndex(index []int) reflect.StructField {
|
||||||
|
@ -155,6 +169,7 @@ func (t *rtype) FieldByIndex(index []int) reflect.StructField {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_FieldByName reflect.(*rtype).FieldByName
|
//go:linkname rtype_FieldByName reflect.(*rtype).FieldByName
|
||||||
|
//go:noescape
|
||||||
func rtype_FieldByName(*rtype, string) (reflect.StructField, bool)
|
func rtype_FieldByName(*rtype, string) (reflect.StructField, bool)
|
||||||
|
|
||||||
func (t *rtype) FieldByName(name string) (reflect.StructField, bool) {
|
func (t *rtype) FieldByName(name string) (reflect.StructField, bool) {
|
||||||
|
@ -162,6 +177,7 @@ func (t *rtype) FieldByName(name string) (reflect.StructField, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_FieldByNameFunc reflect.(*rtype).FieldByNameFunc
|
//go:linkname rtype_FieldByNameFunc reflect.(*rtype).FieldByNameFunc
|
||||||
|
//go:noescape
|
||||||
func rtype_FieldByNameFunc(*rtype, func(string) bool) (reflect.StructField, bool)
|
func rtype_FieldByNameFunc(*rtype, func(string) bool) (reflect.StructField, bool)
|
||||||
|
|
||||||
func (t *rtype) FieldByNameFunc(match func(string) bool) (reflect.StructField, bool) {
|
func (t *rtype) FieldByNameFunc(match func(string) bool) (reflect.StructField, bool) {
|
||||||
|
@ -169,6 +185,7 @@ func (t *rtype) FieldByNameFunc(match func(string) bool) (reflect.StructField, b
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_In reflect.(*rtype).In
|
//go:linkname rtype_In reflect.(*rtype).In
|
||||||
|
//go:noescape
|
||||||
func rtype_In(*rtype, int) reflect.Type
|
func rtype_In(*rtype, int) reflect.Type
|
||||||
|
|
||||||
func (t *rtype) In(i int) reflect.Type {
|
func (t *rtype) In(i int) reflect.Type {
|
||||||
|
@ -176,6 +193,7 @@ func (t *rtype) In(i int) reflect.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Key reflect.(*rtype).Key
|
//go:linkname rtype_Key reflect.(*rtype).Key
|
||||||
|
//go:noescape
|
||||||
func rtype_Key(*rtype) reflect.Type
|
func rtype_Key(*rtype) reflect.Type
|
||||||
|
|
||||||
func (t *rtype) Key() *rtype {
|
func (t *rtype) Key() *rtype {
|
||||||
|
@ -191,6 +209,7 @@ func (t *rtype) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_NumField reflect.(*rtype).NumField
|
//go:linkname rtype_NumField reflect.(*rtype).NumField
|
||||||
|
//go:noescape
|
||||||
func rtype_NumField(*rtype) int
|
func rtype_NumField(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) NumField() int {
|
func (t *rtype) NumField() int {
|
||||||
|
@ -198,6 +217,7 @@ func (t *rtype) NumField() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_NumIn reflect.(*rtype).NumIn
|
//go:linkname rtype_NumIn reflect.(*rtype).NumIn
|
||||||
|
//go:noescape
|
||||||
func rtype_NumIn(*rtype) int
|
func rtype_NumIn(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) NumIn() int {
|
func (t *rtype) NumIn() int {
|
||||||
|
@ -205,6 +225,7 @@ func (t *rtype) NumIn() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_NumOut reflect.(*rtype).NumOut
|
//go:linkname rtype_NumOut reflect.(*rtype).NumOut
|
||||||
|
//go:noescape
|
||||||
func rtype_NumOut(*rtype) int
|
func rtype_NumOut(*rtype) int
|
||||||
|
|
||||||
func (t *rtype) NumOut() int {
|
func (t *rtype) NumOut() int {
|
||||||
|
@ -212,12 +233,19 @@ func (t *rtype) NumOut() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname rtype_Out reflect.(*rtype).Out
|
//go:linkname rtype_Out reflect.(*rtype).Out
|
||||||
|
//go:noescape
|
||||||
func rtype_Out(*rtype, int) reflect.Type
|
func rtype_Out(*rtype, int) reflect.Type
|
||||||
|
|
||||||
func (t *rtype) Out(i int) reflect.Type {
|
func (t *rtype) Out(i int) reflect.Type {
|
||||||
return rtype_Out(t, i)
|
return rtype_Out(t, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname rtype_escape reflect.(*rtype).Kind
|
||||||
|
func rtype_escape(*rtype) reflect.Kind
|
||||||
|
func (t *rtype) escape() {
|
||||||
|
rtype_escape(t)
|
||||||
|
}
|
||||||
|
|
||||||
type interfaceHeader struct {
|
type interfaceHeader struct {
|
||||||
typ *rtype
|
typ *rtype
|
||||||
ptr unsafe.Pointer
|
ptr unsafe.Pointer
|
||||||
|
|
Loading…
Reference in New Issue