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