1
2
3 package ssa
4
5 import (
6 "internal/unsafeheader"
7 "math/bits"
8 "sync"
9 "unsafe"
10 )
11
12 var poolFreeValueSlice [27]sync.Pool
13
14 func (c *Cache) allocValueSlice(n int) []*Value {
15 var s []*Value
16 n2 := n
17 if n2 < 32 {
18 n2 = 32
19 }
20 b := bits.Len(uint(n2 - 1))
21 v := poolFreeValueSlice[b-5].Get()
22 if v == nil {
23 s = make([]*Value, 1<<b)
24 } else {
25 sp := v.(*[]*Value)
26 s = *sp
27 *sp = nil
28 c.hdrValueSlice = append(c.hdrValueSlice, sp)
29 }
30 s = s[:n]
31 return s
32 }
33 func (c *Cache) freeValueSlice(s []*Value) {
34 for i := range s {
35 s[i] = nil
36 }
37 b := bits.Len(uint(cap(s)) - 1)
38 var sp *[]*Value
39 if len(c.hdrValueSlice) == 0 {
40 sp = new([]*Value)
41 } else {
42 sp = c.hdrValueSlice[len(c.hdrValueSlice)-1]
43 c.hdrValueSlice[len(c.hdrValueSlice)-1] = nil
44 c.hdrValueSlice = c.hdrValueSlice[:len(c.hdrValueSlice)-1]
45 }
46 *sp = s
47 poolFreeValueSlice[b-5].Put(sp)
48 }
49
50 var poolFreeLimitSlice [27]sync.Pool
51
52 func (c *Cache) allocLimitSlice(n int) []limit {
53 var s []limit
54 n2 := n
55 if n2 < 8 {
56 n2 = 8
57 }
58 b := bits.Len(uint(n2 - 1))
59 v := poolFreeLimitSlice[b-3].Get()
60 if v == nil {
61 s = make([]limit, 1<<b)
62 } else {
63 sp := v.(*[]limit)
64 s = *sp
65 *sp = nil
66 c.hdrLimitSlice = append(c.hdrLimitSlice, sp)
67 }
68 s = s[:n]
69 return s
70 }
71 func (c *Cache) freeLimitSlice(s []limit) {
72 for i := range s {
73 s[i] = limit{}
74 }
75 b := bits.Len(uint(cap(s)) - 1)
76 var sp *[]limit
77 if len(c.hdrLimitSlice) == 0 {
78 sp = new([]limit)
79 } else {
80 sp = c.hdrLimitSlice[len(c.hdrLimitSlice)-1]
81 c.hdrLimitSlice[len(c.hdrLimitSlice)-1] = nil
82 c.hdrLimitSlice = c.hdrLimitSlice[:len(c.hdrLimitSlice)-1]
83 }
84 *sp = s
85 poolFreeLimitSlice[b-3].Put(sp)
86 }
87
88 var poolFreeSparseSet [27]sync.Pool
89
90 func (c *Cache) allocSparseSet(n int) *sparseSet {
91 var s *sparseSet
92 n2 := n
93 if n2 < 32 {
94 n2 = 32
95 }
96 b := bits.Len(uint(n2 - 1))
97 v := poolFreeSparseSet[b-5].Get()
98 if v == nil {
99 s = newSparseSet(1 << b)
100 } else {
101 s = v.(*sparseSet)
102 }
103 return s
104 }
105 func (c *Cache) freeSparseSet(s *sparseSet) {
106 s.clear()
107 b := bits.Len(uint(s.cap()) - 1)
108 poolFreeSparseSet[b-5].Put(s)
109 }
110
111 var poolFreeSparseMap [27]sync.Pool
112
113 func (c *Cache) allocSparseMap(n int) *sparseMap {
114 var s *sparseMap
115 n2 := n
116 if n2 < 32 {
117 n2 = 32
118 }
119 b := bits.Len(uint(n2 - 1))
120 v := poolFreeSparseMap[b-5].Get()
121 if v == nil {
122 s = newSparseMap(1 << b)
123 } else {
124 s = v.(*sparseMap)
125 }
126 return s
127 }
128 func (c *Cache) freeSparseMap(s *sparseMap) {
129 s.clear()
130 b := bits.Len(uint(s.cap()) - 1)
131 poolFreeSparseMap[b-5].Put(s)
132 }
133
134 var poolFreeSparseMapPos [27]sync.Pool
135
136 func (c *Cache) allocSparseMapPos(n int) *sparseMapPos {
137 var s *sparseMapPos
138 n2 := n
139 if n2 < 32 {
140 n2 = 32
141 }
142 b := bits.Len(uint(n2 - 1))
143 v := poolFreeSparseMapPos[b-5].Get()
144 if v == nil {
145 s = newSparseMapPos(1 << b)
146 } else {
147 s = v.(*sparseMapPos)
148 }
149 return s
150 }
151 func (c *Cache) freeSparseMapPos(s *sparseMapPos) {
152 s.clear()
153 b := bits.Len(uint(s.cap()) - 1)
154 poolFreeSparseMapPos[b-5].Put(s)
155 }
156 func (c *Cache) allocBlockSlice(n int) []*Block {
157 var base *Value
158 var derived *Block
159 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
160 panic("bad")
161 }
162 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
163 b := c.allocValueSlice(int((uintptr(n) + scale - 1) / scale))
164 s := unsafeheader.Slice{
165 Data: unsafe.Pointer(&b[0]),
166 Len: n,
167 Cap: cap(b) * int(scale),
168 }
169 return *(*[]*Block)(unsafe.Pointer(&s))
170 }
171 func (c *Cache) freeBlockSlice(s []*Block) {
172 var base *Value
173 var derived *Block
174 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
175 b := unsafeheader.Slice{
176 Data: unsafe.Pointer(&s[0]),
177 Len: int((uintptr(len(s)) + scale - 1) / scale),
178 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
179 }
180 c.freeValueSlice(*(*[]*Value)(unsafe.Pointer(&b)))
181 }
182 func (c *Cache) allocInt64(n int) []int64 {
183 var base limit
184 var derived int64
185 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
186 panic("bad")
187 }
188 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
189 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
190 s := unsafeheader.Slice{
191 Data: unsafe.Pointer(&b[0]),
192 Len: n,
193 Cap: cap(b) * int(scale),
194 }
195 return *(*[]int64)(unsafe.Pointer(&s))
196 }
197 func (c *Cache) freeInt64(s []int64) {
198 var base limit
199 var derived int64
200 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
201 b := unsafeheader.Slice{
202 Data: unsafe.Pointer(&s[0]),
203 Len: int((uintptr(len(s)) + scale - 1) / scale),
204 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
205 }
206 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
207 }
208 func (c *Cache) allocIntSlice(n int) []int {
209 var base limit
210 var derived int
211 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
212 panic("bad")
213 }
214 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
215 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
216 s := unsafeheader.Slice{
217 Data: unsafe.Pointer(&b[0]),
218 Len: n,
219 Cap: cap(b) * int(scale),
220 }
221 return *(*[]int)(unsafe.Pointer(&s))
222 }
223 func (c *Cache) freeIntSlice(s []int) {
224 var base limit
225 var derived int
226 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
227 b := unsafeheader.Slice{
228 Data: unsafe.Pointer(&s[0]),
229 Len: int((uintptr(len(s)) + scale - 1) / scale),
230 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
231 }
232 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
233 }
234 func (c *Cache) allocInt32Slice(n int) []int32 {
235 var base limit
236 var derived int32
237 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
238 panic("bad")
239 }
240 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
241 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
242 s := unsafeheader.Slice{
243 Data: unsafe.Pointer(&b[0]),
244 Len: n,
245 Cap: cap(b) * int(scale),
246 }
247 return *(*[]int32)(unsafe.Pointer(&s))
248 }
249 func (c *Cache) freeInt32Slice(s []int32) {
250 var base limit
251 var derived int32
252 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
253 b := unsafeheader.Slice{
254 Data: unsafe.Pointer(&s[0]),
255 Len: int((uintptr(len(s)) + scale - 1) / scale),
256 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
257 }
258 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
259 }
260 func (c *Cache) allocInt8Slice(n int) []int8 {
261 var base limit
262 var derived int8
263 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
264 panic("bad")
265 }
266 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
267 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
268 s := unsafeheader.Slice{
269 Data: unsafe.Pointer(&b[0]),
270 Len: n,
271 Cap: cap(b) * int(scale),
272 }
273 return *(*[]int8)(unsafe.Pointer(&s))
274 }
275 func (c *Cache) freeInt8Slice(s []int8) {
276 var base limit
277 var derived int8
278 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
279 b := unsafeheader.Slice{
280 Data: unsafe.Pointer(&s[0]),
281 Len: int((uintptr(len(s)) + scale - 1) / scale),
282 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
283 }
284 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
285 }
286 func (c *Cache) allocBoolSlice(n int) []bool {
287 var base limit
288 var derived bool
289 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
290 panic("bad")
291 }
292 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
293 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
294 s := unsafeheader.Slice{
295 Data: unsafe.Pointer(&b[0]),
296 Len: n,
297 Cap: cap(b) * int(scale),
298 }
299 return *(*[]bool)(unsafe.Pointer(&s))
300 }
301 func (c *Cache) freeBoolSlice(s []bool) {
302 var base limit
303 var derived bool
304 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
305 b := unsafeheader.Slice{
306 Data: unsafe.Pointer(&s[0]),
307 Len: int((uintptr(len(s)) + scale - 1) / scale),
308 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
309 }
310 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
311 }
312 func (c *Cache) allocIDSlice(n int) []ID {
313 var base limit
314 var derived ID
315 if unsafe.Sizeof(base)%unsafe.Sizeof(derived) != 0 {
316 panic("bad")
317 }
318 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
319 b := c.allocLimitSlice(int((uintptr(n) + scale - 1) / scale))
320 s := unsafeheader.Slice{
321 Data: unsafe.Pointer(&b[0]),
322 Len: n,
323 Cap: cap(b) * int(scale),
324 }
325 return *(*[]ID)(unsafe.Pointer(&s))
326 }
327 func (c *Cache) freeIDSlice(s []ID) {
328 var base limit
329 var derived ID
330 scale := unsafe.Sizeof(base) / unsafe.Sizeof(derived)
331 b := unsafeheader.Slice{
332 Data: unsafe.Pointer(&s[0]),
333 Len: int((uintptr(len(s)) + scale - 1) / scale),
334 Cap: int((uintptr(cap(s)) + scale - 1) / scale),
335 }
336 c.freeLimitSlice(*(*[]limit)(unsafe.Pointer(&b)))
337 }
338
View as plain text