1
2
3
4
5
6
7 package codec
8
9 import (
10 "reflect"
11 _ "runtime"
12 "unsafe"
13 )
14
15
16
17
18
19
20
21
22 const (
23
24 mapMaxElemSize = 128
25 )
26
27 func unsafeGrowslice(typ unsafe.Pointer, old unsafeSlice, cap, incr int) (v unsafeSlice) {
28 return growslice(typ, old, cap+incr)
29 }
30
31
32
33
34
35
36
37
38
39
40
41
42 func mapStoresElemIndirect(elemsize uintptr) bool {
43 return elemsize > mapMaxElemSize
44 }
45
46 func mapSet(m, k, v reflect.Value, keyFastKind mapKeyFastKind, valIsIndirect, valIsRef bool) {
47 var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
48 var kptr = unsafeMapKVPtr(urv)
49 urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
50 var vtyp = urv.typ
51 var vptr = unsafeMapKVPtr(urv)
52
53 urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
54 mptr := rvRefPtr(urv)
55
56 var vvptr unsafe.Pointer
57
58
59
60
61
62
63 if valIsIndirect {
64 vvptr = mapassign(urv.typ, mptr, kptr)
65 typedmemmove(vtyp, vvptr, vptr)
66
67 return
68 }
69
70 switch keyFastKind {
71 case mapKeyFastKind32:
72 vvptr = mapassign_fast32(urv.typ, mptr, *(*uint32)(kptr))
73 case mapKeyFastKind32ptr:
74 vvptr = mapassign_fast32ptr(urv.typ, mptr, *(*unsafe.Pointer)(kptr))
75 case mapKeyFastKind64:
76 vvptr = mapassign_fast64(urv.typ, mptr, *(*uint64)(kptr))
77 case mapKeyFastKind64ptr:
78 vvptr = mapassign_fast64ptr(urv.typ, mptr, *(*unsafe.Pointer)(kptr))
79 case mapKeyFastKindStr:
80 vvptr = mapassign_faststr(urv.typ, mptr, *(*string)(kptr))
81 default:
82 vvptr = mapassign(urv.typ, mptr, kptr)
83 }
84
85
86
87
88
89 typedmemmove(vtyp, vvptr, vptr)
90 }
91
92 func mapGet(m, k, v reflect.Value, keyFastKind mapKeyFastKind, valIsIndirect, valIsRef bool) (_ reflect.Value) {
93 var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
94 var kptr = unsafeMapKVPtr(urv)
95 urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
96 mptr := rvRefPtr(urv)
97
98 var vvptr unsafe.Pointer
99 var ok bool
100
101
102
103
104 switch keyFastKind {
105 case mapKeyFastKind32, mapKeyFastKind32ptr:
106 vvptr, ok = mapaccess2_fast32(urv.typ, mptr, *(*uint32)(kptr))
107 case mapKeyFastKind64, mapKeyFastKind64ptr:
108 vvptr, ok = mapaccess2_fast64(urv.typ, mptr, *(*uint64)(kptr))
109 case mapKeyFastKindStr:
110 vvptr, ok = mapaccess2_faststr(urv.typ, mptr, *(*string)(kptr))
111 default:
112 vvptr, ok = mapaccess2(urv.typ, mptr, kptr)
113 }
114
115 if !ok {
116 return
117 }
118
119 urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
120
121 if keyFastKind != 0 && valIsIndirect {
122 urv.ptr = *(*unsafe.Pointer)(vvptr)
123 } else if helperUnsafeDirectAssignMapEntry || valIsRef {
124 urv.ptr = vvptr
125 } else {
126 typedmemmove(urv.typ, urv.ptr, vvptr)
127 }
128
129 return v
130 }
131
132
133 var unsafeZeroArr [1024]byte
134
135
136
137
138
139
140
141 func mapassign_fast32(typ unsafe.Pointer, m unsafe.Pointer, key uint32) unsafe.Pointer
142
143
144
145 func mapassign_fast32ptr(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
146
147
148
149 func mapassign_fast64(typ unsafe.Pointer, m unsafe.Pointer, key uint64) unsafe.Pointer
150
151
152
153 func mapassign_fast64ptr(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
154
155
156
157 func mapassign_faststr(typ unsafe.Pointer, m unsafe.Pointer, s string) unsafe.Pointer
158
159
160
161 func mapaccess2_fast32(typ unsafe.Pointer, m unsafe.Pointer, key uint32) (val unsafe.Pointer, ok bool)
162
163
164
165 func mapaccess2_fast64(typ unsafe.Pointer, m unsafe.Pointer, key uint64) (val unsafe.Pointer, ok bool)
166
167
168
169 func mapaccess2_faststr(typ unsafe.Pointer, m unsafe.Pointer, key string) (val unsafe.Pointer, ok bool)
170
View as plain text