1 #ifndef JEMALLOC_INTERNAL_CACHE_BIN_H
2 #define JEMALLOC_INTERNAL_CACHE_BIN_H
3
4 #include "jemalloc/internal/ql.h"
5 #include "jemalloc/internal/sz.h"
6
7 /*
8 * The cache_bins are the mechanism that the tcache and the arena use to
9 * communicate. The tcache fills from and flushes to the arena by passing a
10 * cache_bin_t to fill/flush. When the arena needs to pull stats from the
11 * tcaches associated with it, it does so by iterating over its
12 * cache_bin_array_descriptor_t objects and reading out per-bin stats it
13 * contains. This makes it so that the arena need not know about the existence
14 * of the tcache at all.
15 */
16
17 /*
18 * The size in bytes of each cache bin stack. We also use this to indicate
19 * *counts* of individual objects.
20 */
21 typedef uint16_t cache_bin_sz_t;
22
23 /*
24 * Leave a noticeable mark pattern on the cache bin stack boundaries, in case a
25 * bug starts leaking those. Make it look like the junk pattern but be distinct
26 * from it.
27 */
28 static const uintptr_t cache_bin_preceding_junk =
29 (uintptr_t)0x7a7a7a7a7a7a7a7aULL;
30 /* Note: a7 vs. 7a above -- this tells you which pointer leaked. */
31 static const uintptr_t cache_bin_trailing_junk =
32 (uintptr_t)0xa7a7a7a7a7a7a7a7ULL;
33
34 /*
35 * That implies the following value, for the maximum number of items in any
36 * individual bin. The cache bins track their bounds looking just at the low
37 * bits of a pointer, compared against a cache_bin_sz_t. So that's
38 * 1 << (sizeof(cache_bin_sz_t) * 8)
39 * bytes spread across pointer sized objects to get the maximum.
40 */
41 #define CACHE_BIN_NCACHED_MAX (((size_t)1 << sizeof(cache_bin_sz_t) * 8) \
42 / sizeof(void *) - 1)
43
44 /*
45 * This lives inside the cache_bin (for locality reasons), and is initialized
46 * alongside it, but is otherwise not modified by any cache bin operations.
47 * It's logically public and maintained by its callers.
48 */
49 typedef struct cache_bin_stats_s cache_bin_stats_t;
50 struct cache_bin_stats_s {
51 /*
52 * Number of allocation requests that corresponded to the size of this
53 * bin.
54 */
55 uint64_t nrequests;
56 };
57
58 /*
59 * Read-only information associated with each element of tcache_t's tbins array
60 * is stored separately, mainly to reduce memory usage.
61 */
62 typedef struct cache_bin_info_s cache_bin_info_t;
63 struct cache_bin_info_s {
64 cache_bin_sz_t ncached_max;
65 };
66
67 /*
68 * Responsible for caching allocations associated with a single size.
69 *
70 * Several pointers are used to track the stack. To save on metadata bytes,
71 * only the stack_head is a full sized pointer (which is dereferenced on the
72 * fastpath), while the others store only the low 16 bits -- this is correct
73 * because a single stack never takes more space than 2^16 bytes, and at the
74 * same time only equality checks are performed on the low bits.
75 *
76 * (low addr) (high addr)
77 * |------stashed------|------available------|------cached-----|
78 * ^ ^ ^ ^
79 * low_bound(derived) low_bits_full stack_head low_bits_empty
80 */
81 typedef struct cache_bin_s cache_bin_t;
82 struct cache_bin_s {
83 /*
84 * The stack grows down. Whenever the bin is nonempty, the head points
85 * to an array entry containing a valid allocation. When it is empty,
86 * the head points to one element past the owned array.
87 */
88 void **stack_head;
89 /*
90 * cur_ptr and stats are both modified frequently. Let's keep them
91 * close so that they have a higher chance of being on the same
92 * cacheline, thus less write-backs.
93 */
94 cache_bin_stats_t tstats;
95
96 /*
97 * The low bits of the address of the first item in the stack that
98 * hasn't been used since the last GC, to track the low water mark (min
99 * # of cached items).
100 *
101 * Since the stack grows down, this is a higher address than
102 * low_bits_full.
103 */
104 uint16_t low_bits_low_water;
105
106 /*
107 * The low bits of the value that stack_head will take on when the array
108 * is full (of cached & stashed items). But remember that stack_head
109 * always points to a valid item when the array is nonempty -- this is
110 * in the array.
111 *
112 * Recall that since the stack grows down, this is the lowest available
113 * address in the array for caching. Only adjusted when stashing items.
114 */
115 uint16_t low_bits_full;
116
117 /*
118 * The low bits of the value that stack_head will take on when the array
119 * is empty.
120 *
121 * The stack grows down -- this is one past the highest address in the
122 * array. Immutable after initialization.
123 */
124 uint16_t low_bits_empty;
125 };
126
127 /*
128 * The cache_bins live inside the tcache, but the arena (by design) isn't
129 * supposed to know much about tcache internals. To let the arena iterate over
130 * associated bins, we keep (with the tcache) a linked list of
131 * cache_bin_array_descriptor_ts that tell the arena how to find the bins.
132 */
133 typedef struct cache_bin_array_descriptor_s cache_bin_array_descriptor_t;
134 struct cache_bin_array_descriptor_s {
135 /*
136 * The arena keeps a list of the cache bins associated with it, for
137 * stats collection.
138 */
139 ql_elm(cache_bin_array_descriptor_t) link;
140 /* Pointers to the tcache bins. */
141 cache_bin_t *bins;
142 };
143
144 static inline void
cache_bin_array_descriptor_init(cache_bin_array_descriptor_t * descriptor,cache_bin_t * bins)145 cache_bin_array_descriptor_init(cache_bin_array_descriptor_t *descriptor,
146 cache_bin_t *bins) {
147 ql_elm_new(descriptor, link);
148 descriptor->bins = bins;
149 }
150
151 JEMALLOC_ALWAYS_INLINE bool
cache_bin_nonfast_aligned(const void * ptr)152 cache_bin_nonfast_aligned(const void *ptr) {
153 if (!config_uaf_detection) {
154 return false;
155 }
156 /*
157 * Currently we use alignment to decide which pointer to junk & stash on
158 * dealloc (for catching use-after-free). In some common cases a
159 * page-aligned check is needed already (sdalloc w/ config_prof), so we
160 * are getting it more or less for free -- no added instructions on
161 * free_fastpath.
162 *
163 * Another way of deciding which pointer to sample, is adding another
164 * thread_event to pick one every N bytes. That also adds no cost on
165 * the fastpath, however it will tend to pick large allocations which is
166 * not the desired behavior.
167 */
168 return ((uintptr_t)ptr & san_cache_bin_nonfast_mask) == 0;
169 }
170
171 /* Returns ncached_max: Upper limit on ncached. */
172 static inline cache_bin_sz_t
cache_bin_info_ncached_max(cache_bin_info_t * info)173 cache_bin_info_ncached_max(cache_bin_info_t *info) {
174 return info->ncached_max;
175 }
176
177 /*
178 * Internal.
179 *
180 * Asserts that the pointer associated with earlier is <= the one associated
181 * with later.
182 */
183 static inline void
cache_bin_assert_earlier(cache_bin_t * bin,uint16_t earlier,uint16_t later)184 cache_bin_assert_earlier(cache_bin_t *bin, uint16_t earlier, uint16_t later) {
185 if (earlier > later) {
186 assert(bin->low_bits_full > bin->low_bits_empty);
187 }
188 }
189
190 /*
191 * Internal.
192 *
193 * Does difference calculations that handle wraparound correctly. Earlier must
194 * be associated with the position earlier in memory.
195 */
196 static inline uint16_t
cache_bin_diff(cache_bin_t * bin,uint16_t earlier,uint16_t later,bool racy)197 cache_bin_diff(cache_bin_t *bin, uint16_t earlier, uint16_t later, bool racy) {
198 /*
199 * When it's racy, bin->low_bits_full can be modified concurrently. It
200 * can cross the uint16_t max value and become less than
201 * bin->low_bits_empty at the time of the check.
202 */
203 if (!racy) {
204 cache_bin_assert_earlier(bin, earlier, later);
205 }
206 return later - earlier;
207 }
208
209 /*
210 * Number of items currently cached in the bin, without checking ncached_max.
211 * We require specifying whether or not the request is racy or not (i.e. whether
212 * or not concurrent modifications are possible).
213 */
214 static inline cache_bin_sz_t
cache_bin_ncached_get_internal(cache_bin_t * bin,bool racy)215 cache_bin_ncached_get_internal(cache_bin_t *bin, bool racy) {
216 cache_bin_sz_t diff = cache_bin_diff(bin,
217 (uint16_t)(uintptr_t)bin->stack_head, bin->low_bits_empty, racy);
218 cache_bin_sz_t n = diff / sizeof(void *);
219 /*
220 * We have undefined behavior here; if this function is called from the
221 * arena stats updating code, then stack_head could change from the
222 * first line to the next one. Morally, these loads should be atomic,
223 * but compilers won't currently generate comparisons with in-memory
224 * operands against atomics, and these variables get accessed on the
225 * fast paths. This should still be "safe" in the sense of generating
226 * the correct assembly for the foreseeable future, though.
227 */
228 assert(n == 0 || *(bin->stack_head) != NULL || racy);
229 return n;
230 }
231
232 /*
233 * Number of items currently cached in the bin, with checking ncached_max. The
234 * caller must know that no concurrent modification of the cache_bin is
235 * possible.
236 */
237 static inline cache_bin_sz_t
cache_bin_ncached_get_local(cache_bin_t * bin,cache_bin_info_t * info)238 cache_bin_ncached_get_local(cache_bin_t *bin, cache_bin_info_t *info) {
239 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin,
240 /* racy */ false);
241 assert(n <= cache_bin_info_ncached_max(info));
242 return n;
243 }
244
245 /*
246 * Internal.
247 *
248 * A pointer to the position one past the end of the backing array.
249 *
250 * Do not call if racy, because both 'bin->stack_head' and 'bin->low_bits_full'
251 * are subject to concurrent modifications.
252 */
253 static inline void **
cache_bin_empty_position_get(cache_bin_t * bin)254 cache_bin_empty_position_get(cache_bin_t *bin) {
255 cache_bin_sz_t diff = cache_bin_diff(bin,
256 (uint16_t)(uintptr_t)bin->stack_head, bin->low_bits_empty,
257 /* racy */ false);
258 uintptr_t empty_bits = (uintptr_t)bin->stack_head + diff;
259 void **ret = (void **)empty_bits;
260
261 assert(ret >= bin->stack_head);
262
263 return ret;
264 }
265
266 /*
267 * Internal.
268 *
269 * Calculates low bits of the lower bound of the usable cache bin's range (see
270 * cache_bin_t visual representation above).
271 *
272 * No values are concurrently modified, so should be safe to read in a
273 * multithreaded environment. Currently concurrent access happens only during
274 * arena statistics collection.
275 */
276 static inline uint16_t
cache_bin_low_bits_low_bound_get(cache_bin_t * bin,cache_bin_info_t * info)277 cache_bin_low_bits_low_bound_get(cache_bin_t *bin, cache_bin_info_t *info) {
278 return (uint16_t)bin->low_bits_empty -
279 info->ncached_max * sizeof(void *);
280 }
281
282 /*
283 * Internal.
284 *
285 * A pointer to the position with the lowest address of the backing array.
286 */
287 static inline void **
cache_bin_low_bound_get(cache_bin_t * bin,cache_bin_info_t * info)288 cache_bin_low_bound_get(cache_bin_t *bin, cache_bin_info_t *info) {
289 cache_bin_sz_t ncached_max = cache_bin_info_ncached_max(info);
290 void **ret = cache_bin_empty_position_get(bin) - ncached_max;
291 assert(ret <= bin->stack_head);
292
293 return ret;
294 }
295
296 /*
297 * As the name implies. This is important since it's not correct to try to
298 * batch fill a nonempty cache bin.
299 */
300 static inline void
cache_bin_assert_empty(cache_bin_t * bin,cache_bin_info_t * info)301 cache_bin_assert_empty(cache_bin_t *bin, cache_bin_info_t *info) {
302 assert(cache_bin_ncached_get_local(bin, info) == 0);
303 assert(cache_bin_empty_position_get(bin) == bin->stack_head);
304 }
305
306 /*
307 * Get low water, but without any of the correctness checking we do for the
308 * caller-usable version, if we are temporarily breaking invariants (like
309 * ncached >= low_water during flush).
310 */
311 static inline cache_bin_sz_t
cache_bin_low_water_get_internal(cache_bin_t * bin)312 cache_bin_low_water_get_internal(cache_bin_t *bin) {
313 return cache_bin_diff(bin, bin->low_bits_low_water,
314 bin->low_bits_empty, /* racy */ false) / sizeof(void *);
315 }
316
317 /* Returns the numeric value of low water in [0, ncached]. */
318 static inline cache_bin_sz_t
cache_bin_low_water_get(cache_bin_t * bin,cache_bin_info_t * info)319 cache_bin_low_water_get(cache_bin_t *bin, cache_bin_info_t *info) {
320 cache_bin_sz_t low_water = cache_bin_low_water_get_internal(bin);
321 assert(low_water <= cache_bin_info_ncached_max(info));
322 assert(low_water <= cache_bin_ncached_get_local(bin, info));
323
324 cache_bin_assert_earlier(bin, (uint16_t)(uintptr_t)bin->stack_head,
325 bin->low_bits_low_water);
326
327 return low_water;
328 }
329
330 /*
331 * Indicates that the current cache bin position should be the low water mark
332 * going forward.
333 */
334 static inline void
cache_bin_low_water_set(cache_bin_t * bin)335 cache_bin_low_water_set(cache_bin_t *bin) {
336 bin->low_bits_low_water = (uint16_t)(uintptr_t)bin->stack_head;
337 }
338
339 static inline void
cache_bin_low_water_adjust(cache_bin_t * bin)340 cache_bin_low_water_adjust(cache_bin_t *bin) {
341 if (cache_bin_ncached_get_internal(bin, /* racy */ false)
342 < cache_bin_low_water_get_internal(bin)) {
343 cache_bin_low_water_set(bin);
344 }
345 }
346
347 JEMALLOC_ALWAYS_INLINE void *
cache_bin_alloc_impl(cache_bin_t * bin,bool * success,bool adjust_low_water)348 cache_bin_alloc_impl(cache_bin_t *bin, bool *success, bool adjust_low_water) {
349 /*
350 * success (instead of ret) should be checked upon the return of this
351 * function. We avoid checking (ret == NULL) because there is never a
352 * null stored on the avail stack (which is unknown to the compiler),
353 * and eagerly checking ret would cause pipeline stall (waiting for the
354 * cacheline).
355 */
356
357 /*
358 * This may read from the empty position; however the loaded value won't
359 * be used. It's safe because the stack has one more slot reserved.
360 */
361 void *ret = *bin->stack_head;
362 uint16_t low_bits = (uint16_t)(uintptr_t)bin->stack_head;
363 void **new_head = bin->stack_head + 1;
364
365 /*
366 * Note that the low water mark is at most empty; if we pass this check,
367 * we know we're non-empty.
368 */
369 if (likely(low_bits != bin->low_bits_low_water)) {
370 bin->stack_head = new_head;
371 *success = true;
372 return ret;
373 }
374 if (!adjust_low_water) {
375 *success = false;
376 return NULL;
377 }
378 /*
379 * In the fast-path case where we call alloc_easy and then alloc, the
380 * previous checking and computation is optimized away -- we didn't
381 * actually commit any of our operations.
382 */
383 if (likely(low_bits != bin->low_bits_empty)) {
384 bin->stack_head = new_head;
385 bin->low_bits_low_water = (uint16_t)(uintptr_t)new_head;
386 *success = true;
387 return ret;
388 }
389 *success = false;
390 return NULL;
391 }
392
393 /*
394 * Allocate an item out of the bin, failing if we're at the low-water mark.
395 */
396 JEMALLOC_ALWAYS_INLINE void *
cache_bin_alloc_easy(cache_bin_t * bin,bool * success)397 cache_bin_alloc_easy(cache_bin_t *bin, bool *success) {
398 /* We don't look at info if we're not adjusting low-water. */
399 return cache_bin_alloc_impl(bin, success, false);
400 }
401
402 /*
403 * Allocate an item out of the bin, even if we're currently at the low-water
404 * mark (and failing only if the bin is empty).
405 */
406 JEMALLOC_ALWAYS_INLINE void *
cache_bin_alloc(cache_bin_t * bin,bool * success)407 cache_bin_alloc(cache_bin_t *bin, bool *success) {
408 return cache_bin_alloc_impl(bin, success, true);
409 }
410
411 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t
cache_bin_alloc_batch(cache_bin_t * bin,size_t num,void ** out)412 cache_bin_alloc_batch(cache_bin_t *bin, size_t num, void **out) {
413 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin,
414 /* racy */ false);
415 if (n > num) {
416 n = (cache_bin_sz_t)num;
417 }
418 memcpy(out, bin->stack_head, n * sizeof(void *));
419 bin->stack_head += n;
420 cache_bin_low_water_adjust(bin);
421
422 return n;
423 }
424
425 JEMALLOC_ALWAYS_INLINE bool
cache_bin_full(cache_bin_t * bin)426 cache_bin_full(cache_bin_t *bin) {
427 return ((uint16_t)(uintptr_t)bin->stack_head == bin->low_bits_full);
428 }
429
430 /*
431 * Free an object into the given bin. Fails only if the bin is full.
432 */
433 JEMALLOC_ALWAYS_INLINE bool
cache_bin_dalloc_easy(cache_bin_t * bin,void * ptr)434 cache_bin_dalloc_easy(cache_bin_t *bin, void *ptr) {
435 if (unlikely(cache_bin_full(bin))) {
436 return false;
437 }
438
439 bin->stack_head--;
440 *bin->stack_head = ptr;
441 cache_bin_assert_earlier(bin, bin->low_bits_full,
442 (uint16_t)(uintptr_t)bin->stack_head);
443
444 return true;
445 }
446
447 /* Returns false if failed to stash (i.e. bin is full). */
448 JEMALLOC_ALWAYS_INLINE bool
cache_bin_stash(cache_bin_t * bin,void * ptr)449 cache_bin_stash(cache_bin_t *bin, void *ptr) {
450 if (cache_bin_full(bin)) {
451 return false;
452 }
453
454 /* Stash at the full position, in the [full, head) range. */
455 uint16_t low_bits_head = (uint16_t)(uintptr_t)bin->stack_head;
456 /* Wraparound handled as well. */
457 uint16_t diff = cache_bin_diff(bin, bin->low_bits_full, low_bits_head,
458 /* racy */ false);
459 *(void **)((uintptr_t)bin->stack_head - diff) = ptr;
460
461 assert(!cache_bin_full(bin));
462 bin->low_bits_full += sizeof(void *);
463 cache_bin_assert_earlier(bin, bin->low_bits_full, low_bits_head);
464
465 return true;
466 }
467
468 /*
469 * Get the number of stashed pointers.
470 *
471 * When called from a thread not owning the TLS (i.e. racy = true), it's
472 * important to keep in mind that 'bin->stack_head' and 'bin->low_bits_full' can
473 * be modified concurrently and almost none assertions about their values can be
474 * made.
475 */
476 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t
cache_bin_nstashed_get_internal(cache_bin_t * bin,cache_bin_info_t * info,bool racy)477 cache_bin_nstashed_get_internal(cache_bin_t *bin, cache_bin_info_t *info,
478 bool racy) {
479 cache_bin_sz_t ncached_max = cache_bin_info_ncached_max(info);
480 uint16_t low_bits_low_bound = cache_bin_low_bits_low_bound_get(bin,
481 info);
482
483 cache_bin_sz_t n = cache_bin_diff(bin, low_bits_low_bound,
484 bin->low_bits_full, racy) / sizeof(void *);
485 assert(n <= ncached_max);
486
487 if (!racy) {
488 /* Below are for assertions only. */
489 void **low_bound = cache_bin_low_bound_get(bin, info);
490
491 assert((uint16_t)(uintptr_t)low_bound == low_bits_low_bound);
492 void *stashed = *(low_bound + n - 1);
493 bool aligned = cache_bin_nonfast_aligned(stashed);
494 #ifdef JEMALLOC_JET
495 /* Allow arbitrary pointers to be stashed in tests. */
496 aligned = true;
497 #endif
498 assert(n == 0 || (stashed != NULL && aligned));
499 }
500
501 return n;
502 }
503
504 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t
cache_bin_nstashed_get_local(cache_bin_t * bin,cache_bin_info_t * info)505 cache_bin_nstashed_get_local(cache_bin_t *bin, cache_bin_info_t *info) {
506 cache_bin_sz_t n = cache_bin_nstashed_get_internal(bin, info,
507 /* racy */ false);
508 assert(n <= cache_bin_info_ncached_max(info));
509 return n;
510 }
511
512 /*
513 * Obtain a racy view of the number of items currently in the cache bin, in the
514 * presence of possible concurrent modifications.
515 */
516 static inline void
cache_bin_nitems_get_remote(cache_bin_t * bin,cache_bin_info_t * info,cache_bin_sz_t * ncached,cache_bin_sz_t * nstashed)517 cache_bin_nitems_get_remote(cache_bin_t *bin, cache_bin_info_t *info,
518 cache_bin_sz_t *ncached, cache_bin_sz_t *nstashed) {
519 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin, /* racy */ true);
520 assert(n <= cache_bin_info_ncached_max(info));
521 *ncached = n;
522
523 n = cache_bin_nstashed_get_internal(bin, info, /* racy */ true);
524 assert(n <= cache_bin_info_ncached_max(info));
525 *nstashed = n;
526 /* Note that cannot assert ncached + nstashed <= ncached_max (racy). */
527 }
528
529 /*
530 * Filling and flushing are done in batch, on arrays of void *s. For filling,
531 * the arrays go forward, and can be accessed with ordinary array arithmetic.
532 * For flushing, we work from the end backwards, and so need to use special
533 * accessors that invert the usual ordering.
534 *
535 * This is important for maintaining first-fit; the arena code fills with
536 * earliest objects first, and so those are the ones we should return first for
537 * cache_bin_alloc calls. When flushing, we should flush the objects that we
538 * wish to return later; those at the end of the array. This is better for the
539 * first-fit heuristic as well as for cache locality; the most recently freed
540 * objects are the ones most likely to still be in cache.
541 *
542 * This all sounds very hand-wavey and theoretical, but reverting the ordering
543 * on one or the other pathway leads to measurable slowdowns.
544 */
545
546 typedef struct cache_bin_ptr_array_s cache_bin_ptr_array_t;
547 struct cache_bin_ptr_array_s {
548 cache_bin_sz_t n;
549 void **ptr;
550 };
551
552 /*
553 * Declare a cache_bin_ptr_array_t sufficient for nval items.
554 *
555 * In the current implementation, this could be just part of a
556 * cache_bin_ptr_array_init_... call, since we reuse the cache bin stack memory.
557 * Indirecting behind a macro, though, means experimenting with linked-list
558 * representations is easy (since they'll require an alloca in the calling
559 * frame).
560 */
561 #define CACHE_BIN_PTR_ARRAY_DECLARE(name, nval) \
562 cache_bin_ptr_array_t name; \
563 name.n = (nval)
564
565 /*
566 * Start a fill. The bin must be empty, and This must be followed by a
567 * finish_fill call before doing any alloc/dalloc operations on the bin.
568 */
569 static inline void
cache_bin_init_ptr_array_for_fill(cache_bin_t * bin,cache_bin_info_t * info,cache_bin_ptr_array_t * arr,cache_bin_sz_t nfill)570 cache_bin_init_ptr_array_for_fill(cache_bin_t *bin, cache_bin_info_t *info,
571 cache_bin_ptr_array_t *arr, cache_bin_sz_t nfill) {
572 cache_bin_assert_empty(bin, info);
573 arr->ptr = cache_bin_empty_position_get(bin) - nfill;
574 }
575
576 /*
577 * While nfill in cache_bin_init_ptr_array_for_fill is the number we *intend* to
578 * fill, nfilled here is the number we actually filled (which may be less, in
579 * case of OOM.
580 */
581 static inline void
cache_bin_finish_fill(cache_bin_t * bin,cache_bin_info_t * info,cache_bin_ptr_array_t * arr,cache_bin_sz_t nfilled)582 cache_bin_finish_fill(cache_bin_t *bin, cache_bin_info_t *info,
583 cache_bin_ptr_array_t *arr, cache_bin_sz_t nfilled) {
584 cache_bin_assert_empty(bin, info);
585 void **empty_position = cache_bin_empty_position_get(bin);
586 if (nfilled < arr->n) {
587 memmove(empty_position - nfilled, empty_position - arr->n,
588 nfilled * sizeof(void *));
589 }
590 bin->stack_head = empty_position - nfilled;
591 }
592
593 /*
594 * Same deal, but with flush. Unlike fill (which can fail), the user must flush
595 * everything we give them.
596 */
597 static inline void
cache_bin_init_ptr_array_for_flush(cache_bin_t * bin,cache_bin_info_t * info,cache_bin_ptr_array_t * arr,cache_bin_sz_t nflush)598 cache_bin_init_ptr_array_for_flush(cache_bin_t *bin, cache_bin_info_t *info,
599 cache_bin_ptr_array_t *arr, cache_bin_sz_t nflush) {
600 arr->ptr = cache_bin_empty_position_get(bin) - nflush;
601 assert(cache_bin_ncached_get_local(bin, info) == 0
602 || *arr->ptr != NULL);
603 }
604
605 static inline void
cache_bin_finish_flush(cache_bin_t * bin,cache_bin_info_t * info,cache_bin_ptr_array_t * arr,cache_bin_sz_t nflushed)606 cache_bin_finish_flush(cache_bin_t *bin, cache_bin_info_t *info,
607 cache_bin_ptr_array_t *arr, cache_bin_sz_t nflushed) {
608 unsigned rem = cache_bin_ncached_get_local(bin, info) - nflushed;
609 memmove(bin->stack_head + nflushed, bin->stack_head,
610 rem * sizeof(void *));
611 bin->stack_head = bin->stack_head + nflushed;
612 cache_bin_low_water_adjust(bin);
613 }
614
615 static inline void
cache_bin_init_ptr_array_for_stashed(cache_bin_t * bin,szind_t binind,cache_bin_info_t * info,cache_bin_ptr_array_t * arr,cache_bin_sz_t nstashed)616 cache_bin_init_ptr_array_for_stashed(cache_bin_t *bin, szind_t binind,
617 cache_bin_info_t *info, cache_bin_ptr_array_t *arr,
618 cache_bin_sz_t nstashed) {
619 assert(nstashed > 0);
620 assert(cache_bin_nstashed_get_local(bin, info) == nstashed);
621
622 void **low_bound = cache_bin_low_bound_get(bin, info);
623 arr->ptr = low_bound;
624 assert(*arr->ptr != NULL);
625 }
626
627 static inline void
cache_bin_finish_flush_stashed(cache_bin_t * bin,cache_bin_info_t * info)628 cache_bin_finish_flush_stashed(cache_bin_t *bin, cache_bin_info_t *info) {
629 void **low_bound = cache_bin_low_bound_get(bin, info);
630
631 /* Reset the bin local full position. */
632 bin->low_bits_full = (uint16_t)(uintptr_t)low_bound;
633 assert(cache_bin_nstashed_get_local(bin, info) == 0);
634 }
635
636 /*
637 * Initialize a cache_bin_info to represent up to the given number of items in
638 * the cache_bins it is associated with.
639 */
640 void cache_bin_info_init(cache_bin_info_t *bin_info,
641 cache_bin_sz_t ncached_max);
642 /*
643 * Given an array of initialized cache_bin_info_ts, determine how big an
644 * allocation is required to initialize a full set of cache_bin_ts.
645 */
646 void cache_bin_info_compute_alloc(cache_bin_info_t *infos, szind_t ninfos,
647 size_t *size, size_t *alignment);
648
649 /*
650 * Actually initialize some cache bins. Callers should allocate the backing
651 * memory indicated by a call to cache_bin_compute_alloc. They should then
652 * preincrement, call init once for each bin and info, and then call
653 * cache_bin_postincrement. *alloc_cur will then point immediately past the end
654 * of the allocation.
655 */
656 void cache_bin_preincrement(cache_bin_info_t *infos, szind_t ninfos,
657 void *alloc, size_t *cur_offset);
658 void cache_bin_postincrement(cache_bin_info_t *infos, szind_t ninfos,
659 void *alloc, size_t *cur_offset);
660 void cache_bin_init(cache_bin_t *bin, cache_bin_info_t *info, void *alloc,
661 size_t *cur_offset);
662
663 /*
664 * If a cache bin was zero initialized (either because it lives in static or
665 * thread-local storage, or was memset to 0), this function indicates whether or
666 * not cache_bin_init was called on it.
667 */
668 bool cache_bin_still_zero_initialized(cache_bin_t *bin);
669
670 #endif /* JEMALLOC_INTERNAL_CACHE_BIN_H */
671