cache_bin.h 22 KB

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