1 /******************************************************************************/
2 #ifdef JEMALLOC_H_TYPES
5 * Subpages are an artificially designated partitioning of pages. Their only
6 * purpose is to support subpage-spaced size classes.
8 * There must be at least 4 subpages per page, due to the way size classes are
12 #define SUBPAGE ((size_t)(1U << LG_SUBPAGE))
13 #define SUBPAGE_MASK (SUBPAGE - 1)
15 /* Return the smallest subpage multiple that is >= s. */
16 #define SUBPAGE_CEILING(s) \
17 (((s) + SUBPAGE_MASK) & ~SUBPAGE_MASK)
20 /* Smallest size class to support. */
21 # define LG_TINY_MIN LG_SIZEOF_PTR
22 # define TINY_MIN (1U << LG_TINY_MIN)
26 * Maximum size class that is a multiple of the quantum, but not (necessarily)
27 * a power of 2. Above this size, allocations are rounded up to the nearest
30 #define LG_QSPACE_MAX_DEFAULT 7
33 * Maximum size class that is a multiple of the cacheline, but not (necessarily)
34 * a power of 2. Above this size, allocations are rounded up to the nearest
37 #define LG_CSPACE_MAX_DEFAULT 9
40 * RUN_MAX_OVRHD indicates maximum desired run header overhead. Runs are sized
41 * as small as possible such that this setting is still honored, without
42 * violating other constraints. The goal is to make runs as small as possible
43 * without exceeding a per run external fragmentation threshold.
45 * We use binary fixed point math for overhead computations, where the binary
46 * point is implicitly RUN_BFP bits to the left.
48 * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
49 * honored for some/all object sizes, since when heap profiling is enabled
50 * there is one pointer of header overhead per object (plus a constant). This
51 * constraint is relaxed (ignored) for runs that are so small that the
52 * per-region overhead is greater than:
54 * (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
57 /* \/ Implicit binary fixed point. */
58 #define RUN_MAX_OVRHD 0x0000003dU
59 #define RUN_MAX_OVRHD_RELAX 0x00001800U
61 /* Maximum number of regions in one run. */
62 #define LG_RUN_MAXREGS 11
63 #define RUN_MAXREGS (1U << LG_RUN_MAXREGS)
66 * The minimum ratio of active:dirty pages per arena is computed as:
68 * (nactive >> opt_lg_dirty_mult) >= ndirty
70 * So, supposing that opt_lg_dirty_mult is 5, there can be no less than 32
71 * times as many active pages as dirty pages.
73 #define LG_DIRTY_MULT_DEFAULT 5
75 typedef struct arena_chunk_map_s arena_chunk_map_t
;
76 typedef struct arena_chunk_s arena_chunk_t
;
77 typedef struct arena_run_s arena_run_t
;
78 typedef struct arena_bin_info_s arena_bin_info_t
;
79 typedef struct arena_bin_s arena_bin_t
;
80 typedef struct arena_s arena_t
;
82 #endif /* JEMALLOC_H_TYPES */
83 /******************************************************************************/
84 #ifdef JEMALLOC_H_STRUCTS
86 /* Each element of the chunk map corresponds to one page within the chunk. */
87 struct arena_chunk_map_s
{
90 * Linkage for run trees. There are two disjoint uses:
92 * 1) arena_t's runs_avail_{clean,dirty} trees.
93 * 2) arena_run_t conceptually uses this linkage for in-use
94 * non-full runs, rather than directly embedding linkage.
96 rb_node(arena_chunk_map_t
) rb_link
;
98 * List of runs currently in purgatory. arena_chunk_purge()
99 * temporarily allocates runs that contain dirty pages while
100 * purging, so that other threads cannot use the runs while the
101 * purging thread is operating without the arena lock held.
103 ql_elm(arena_chunk_map_t
) ql_link
;
107 /* Profile counters, used for large object runs. */
108 prof_ctx_t
*prof_ctx
;
112 * Run address (or size) and various flags are stored together. The bit
113 * layout looks like (assuming 32-bit system):
115 * ???????? ???????? ????---- ----dula
117 * ? : Unallocated: Run address for first/last pages, unset for internal
119 * Small: Run page offset.
120 * Large: Run size for first page, unset for trailing pages.
127 * Following are example bit patterns for the three types of runs.
129 * p : run page offset
131 * c : (binind+1) for size class (used only if prof_promote is true)
138 * Unallocated (clean):
139 * ssssssss ssssssss ssss---- ----du-a
140 * xxxxxxxx xxxxxxxx xxxx---- -----Uxx
141 * ssssssss ssssssss ssss---- ----dU-a
143 * Unallocated (dirty):
144 * ssssssss ssssssss ssss---- ----D--a
145 * xxxxxxxx xxxxxxxx xxxx---- ----xxxx
146 * ssssssss ssssssss ssss---- ----D--a
149 * pppppppp pppppppp pppp---- ----d--A
150 * pppppppp pppppppp pppp---- -------A
151 * pppppppp pppppppp pppp---- ----d--A
154 * ssssssss ssssssss ssss---- ----D-LA
155 * xxxxxxxx xxxxxxxx xxxx---- ----xxxx
156 * -------- -------- -------- ----D-LA
158 * Large (sampled, size <= PAGE_SIZE):
159 * ssssssss ssssssss sssscccc ccccD-LA
161 * Large (not sampled, size == PAGE_SIZE):
162 * ssssssss ssssssss ssss---- ----D-LA
166 #define CHUNK_MAP_CLASS_SHIFT 4
167 #define CHUNK_MAP_CLASS_MASK ((size_t)0xff0U)
169 #define CHUNK_MAP_FLAGS_MASK ((size_t)0xfU)
170 #define CHUNK_MAP_DIRTY ((size_t)0x8U)
171 #define CHUNK_MAP_UNZEROED ((size_t)0x4U)
172 #define CHUNK_MAP_LARGE ((size_t)0x2U)
173 #define CHUNK_MAP_ALLOCATED ((size_t)0x1U)
174 #define CHUNK_MAP_KEY CHUNK_MAP_ALLOCATED
176 typedef rb_tree(arena_chunk_map_t
) arena_avail_tree_t
;
177 typedef rb_tree(arena_chunk_map_t
) arena_run_tree_t
;
179 /* Arena chunk header. */
180 struct arena_chunk_s
{
181 /* Arena that owns the chunk. */
184 /* Linkage for the arena's chunks_dirty list. */
185 ql_elm(arena_chunk_t
) link_dirty
;
188 * True if the chunk is currently in the chunks_dirty list, due to
189 * having at some point contained one or more dirty pages. Removal
190 * from chunks_dirty is lazy, so (dirtied && ndirty == 0) is possible.
194 /* Number of dirty pages. */
198 * Map of pages within chunk that keeps track of free/large/small. The
199 * first map_bias entries are omitted, since the chunk header does not
200 * need to be tracked in the map. This omission saves a header page
201 * for common chunk sizes (e.g. 4 MiB).
203 arena_chunk_map_t map
[1]; /* Dynamically sized. */
205 typedef rb_tree(arena_chunk_t
) arena_chunk_tree_t
;
208 #ifdef JEMALLOC_DEBUG
210 # define ARENA_RUN_MAGIC 0x384adf93
213 /* Bin this run is associated with. */
216 /* Index of next region that has never been allocated, or nregs. */
219 /* Number of free regions in run. */
224 * Read-only information associated with each element of arena_t's bins array
225 * is stored separately, partly to reduce memory usage (only one copy, rather
226 * than one per arena), but mainly to avoid false cacheline sharing.
228 struct arena_bin_info_s
{
229 /* Size of regions in a run for this bin's size class. */
232 /* Total size of a run for this bin's size class. */
235 /* Total number of regions in a run for this bin's size class. */
239 * Offset of first bitmap_t element in a run header for this bin's size
242 uint32_t bitmap_offset
;
245 * Metadata used to manipulate bitmaps for runs associated with this
248 bitmap_info_t bitmap_info
;
252 * Offset of first (prof_ctx_t *) in a run header for this bin's size
253 * class, or 0 if (opt_prof == false).
255 uint32_t ctx0_offset
;
258 /* Offset of first region in a run for this bin's size class. */
259 uint32_t reg0_offset
;
264 * All operations on runcur, runs, and stats require that lock be
265 * locked. Run allocation/deallocation are protected by the arena lock,
266 * which may be acquired while holding one or more bin locks, but not
272 * Current run being used to service allocations of this bin's size
278 * Tree of non-full runs. This tree is used when looking for an
279 * existing run when runcur is no longer usable. We choose the
280 * non-full run that is lowest in memory; this policy tends to keep
281 * objects packed well, and it can also help reduce the number of
282 * almost-empty chunks.
284 arena_run_tree_t runs
;
286 #ifdef JEMALLOC_STATS
287 /* Bin statistics. */
288 malloc_bin_stats_t stats
;
293 #ifdef JEMALLOC_DEBUG
295 # define ARENA_MAGIC 0x947d3d24
298 /* This arena's index within the arenas array. */
302 * Number of threads currently assigned to this arena. This field is
303 * protected by arenas_lock.
308 * There are three classes of arena operations from a locking
310 * 1) Thread asssignment (modifies nthreads) is protected by
312 * 2) Bin-related operations are protected by bin locks.
313 * 3) Chunk- and run-related operations are protected by this mutex.
317 #ifdef JEMALLOC_STATS
319 # ifdef JEMALLOC_TCACHE
321 * List of tcaches for extant threads associated with this arena.
322 * Stats from these are merged incrementally, and at exit.
324 ql_head(tcache_t
) tcache_ql
;
329 uint64_t prof_accumbytes
;
332 /* List of dirty-page-containing chunks this arena manages. */
333 ql_head(arena_chunk_t
) chunks_dirty
;
336 * In order to avoid rapid chunk allocation/deallocation when an arena
337 * oscillates right on the cusp of needing a new chunk, cache the most
338 * recently freed chunk. The spare is left in the arena's chunk trees
339 * until it is deleted.
341 * There is one spare chunk per arena, rather than one spare total, in
342 * order to avoid interactions between multiple threads that could make
343 * a single spare inadequate.
345 arena_chunk_t
*spare
;
347 /* Number of pages in active runs. */
351 * Current count of pages within unused runs that are potentially
352 * dirty, and for which madvise(... MADV_DONTNEED) has not been called.
353 * By tracking this, we can institute a limit on how much dirty unused
354 * memory is mapped for each arena.
359 * Approximate number of pages being purged. It is possible for
360 * multiple threads to purge dirty pages concurrently, and they use
361 * npurgatory to indicate the total number of pages all threads are
362 * attempting to purge.
367 * Size/address-ordered trees of this arena's available runs. The trees
368 * are used for first-best-fit run allocation. The dirty tree contains
369 * runs with dirty pages (i.e. very likely to have been touched and
370 * therefore have associated physical pages), whereas the clean tree
371 * contains runs with pages that either have no associated physical
372 * pages, or have pages that the kernel may recycle at any time due to
373 * previous madvise(2) calls. The dirty tree is used in preference to
374 * the clean tree for allocations, because using dirty pages reduces
375 * the amount of dirty purging necessary to keep the active:dirty page
376 * ratio below the purge threshold.
378 arena_avail_tree_t runs_avail_clean
;
379 arena_avail_tree_t runs_avail_dirty
;
382 * bins is used to store trees of free regions of the following sizes,
383 * assuming a 64-bit system with 16-byte quantum, 4 KiB page size, and
384 * default MALLOC_CONF.
414 arena_bin_t bins
[1]; /* Dynamically sized. */
417 #endif /* JEMALLOC_H_STRUCTS */
418 /******************************************************************************/
419 #ifdef JEMALLOC_H_EXTERNS
421 extern size_t opt_lg_qspace_max
;
422 extern size_t opt_lg_cspace_max
;
423 extern ssize_t opt_lg_dirty_mult
;
425 * small_size2bin is a compact lookup table that rounds request sizes up to
426 * size classes. In order to reduce cache footprint, the table is compressed,
427 * and all accesses are via the SMALL_SIZE2BIN macro.
429 extern uint8_t const *small_size2bin
;
430 #define SMALL_SIZE2BIN(s) (small_size2bin[(s-1) >> LG_TINY_MIN])
432 extern arena_bin_info_t
*arena_bin_info
;
434 /* Various bin-related settings. */
435 #ifdef JEMALLOC_TINY /* Number of (2^n)-spaced tiny bins. */
436 # define ntbins ((unsigned)(LG_QUANTUM - LG_TINY_MIN))
440 extern unsigned nqbins
; /* Number of quantum-spaced bins. */
441 extern unsigned ncbins
; /* Number of cacheline-spaced bins. */
442 extern unsigned nsbins
; /* Number of subpage-spaced bins. */
443 extern unsigned nbins
;
445 # define tspace_max ((size_t)(QUANTUM >> 1))
447 #define qspace_min QUANTUM
448 extern size_t qspace_max
;
449 extern size_t cspace_min
;
450 extern size_t cspace_max
;
451 extern size_t sspace_min
;
452 extern size_t sspace_max
;
453 #define small_maxclass sspace_max
455 #define nlclasses (chunk_npages - map_bias)
457 void arena_purge_all(arena_t
*arena
);
459 void arena_prof_accum(arena_t
*arena
, uint64_t accumbytes
);
461 #ifdef JEMALLOC_TCACHE
462 void arena_tcache_fill_small(arena_t
*arena
, tcache_bin_t
*tbin
,
464 # ifdef JEMALLOC_PROF
465 , uint64_t prof_accumbytes
469 void *arena_malloc_small(arena_t
*arena
, size_t size
, bool zero
);
470 void *arena_malloc_large(arena_t
*arena
, size_t size
, bool zero
);
471 void *arena_malloc(size_t size
, bool zero
);
472 void *arena_palloc(arena_t
*arena
, size_t size
, size_t alloc_size
,
473 size_t alignment
, bool zero
);
474 size_t arena_salloc(const void *ptr
);
476 void arena_prof_promoted(const void *ptr
, size_t size
);
477 size_t arena_salloc_demote(const void *ptr
);
479 void arena_dalloc_bin(arena_t
*arena
, arena_chunk_t
*chunk
, void *ptr
,
480 arena_chunk_map_t
*mapelm
);
481 void arena_dalloc_large(arena_t
*arena
, arena_chunk_t
*chunk
, void *ptr
);
482 #ifdef JEMALLOC_STATS
483 void arena_stats_merge(arena_t
*arena
, size_t *nactive
, size_t *ndirty
,
484 arena_stats_t
*astats
, malloc_bin_stats_t
*bstats
,
485 malloc_large_stats_t
*lstats
);
487 void *arena_ralloc_no_move(void *ptr
, size_t oldsize
, size_t size
,
488 size_t extra
, bool zero
);
489 void *arena_ralloc(void *ptr
, size_t oldsize
, size_t size
, size_t extra
,
490 size_t alignment
, bool zero
);
491 bool arena_new(arena_t
*arena
, unsigned ind
);
492 bool arena_boot(void);
494 #endif /* JEMALLOC_H_EXTERNS */
495 /******************************************************************************/
496 #ifdef JEMALLOC_H_INLINES
498 #ifndef JEMALLOC_ENABLE_INLINE
499 size_t arena_bin_index(arena_t
*arena
, arena_bin_t
*bin
);
500 unsigned arena_run_regind(arena_run_t
*run
, arena_bin_info_t
*bin_info
,
502 # ifdef JEMALLOC_PROF
503 prof_ctx_t
*arena_prof_ctx_get(const void *ptr
);
504 void arena_prof_ctx_set(const void *ptr
, prof_ctx_t
*ctx
);
506 void arena_dalloc(arena_t
*arena
, arena_chunk_t
*chunk
, void *ptr
);
509 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_))
510 JEMALLOC_INLINE
size_t
511 arena_bin_index(arena_t
*arena
, arena_bin_t
*bin
)
513 size_t binind
= bin
- arena
->bins
;
514 assert(binind
< nbins
);
518 JEMALLOC_INLINE
unsigned
519 arena_run_regind(arena_run_t
*run
, arena_bin_info_t
*bin_info
, const void *ptr
)
521 unsigned shift
, diff
, regind
;
524 dassert(run
->magic
== ARENA_RUN_MAGIC
);
526 * Freeing a pointer lower than region zero can cause assertion
529 assert((uintptr_t)ptr
>= (uintptr_t)run
+
530 (uintptr_t)bin_info
->reg0_offset
);
533 * Avoid doing division with a variable divisor if possible. Using
534 * actual division here can reduce allocator throughput by over 20%!
536 diff
= (unsigned)((uintptr_t)ptr
- (uintptr_t)run
-
537 bin_info
->reg0_offset
);
539 /* Rescale (factor powers of 2 out of the numerator and denominator). */
540 size
= bin_info
->reg_size
;
541 shift
= ffs(size
) - 1;
546 /* The divisor was a power of 2. */
550 * To divide by a number D that is not a power of two we
551 * multiply by (2^21 / D) and then right shift by 21 positions.
557 * (X * size_invs[D - 3]) >> SIZE_INV_SHIFT
559 * We can omit the first three elements, because we never
560 * divide by 0, and 1 and 2 are both powers of two, which are
563 #define SIZE_INV_SHIFT ((sizeof(unsigned) << 3) - LG_RUN_MAXREGS)
564 #define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s)) + 1)
565 static const unsigned size_invs
[] = {
567 SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
568 SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
569 SIZE_INV(12), SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
570 SIZE_INV(16), SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
571 SIZE_INV(20), SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
572 SIZE_INV(24), SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
573 SIZE_INV(28), SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
576 if (size
<= ((sizeof(size_invs
) / sizeof(unsigned)) + 2))
577 regind
= (diff
* size_invs
[size
- 3]) >> SIZE_INV_SHIFT
;
579 regind
= diff
/ size
;
581 #undef SIZE_INV_SHIFT
583 assert(diff
== regind
* size
);
584 assert(regind
< bin_info
->nregs
);
590 JEMALLOC_INLINE prof_ctx_t
*
591 arena_prof_ctx_get(const void *ptr
)
594 arena_chunk_t
*chunk
;
595 size_t pageind
, mapbits
;
598 assert(CHUNK_ADDR2BASE(ptr
) != ptr
);
600 chunk
= (arena_chunk_t
*)CHUNK_ADDR2BASE(ptr
);
601 pageind
= ((uintptr_t)ptr
- (uintptr_t)chunk
) >> PAGE_SHIFT
;
602 mapbits
= chunk
->map
[pageind
-map_bias
].bits
;
603 assert((mapbits
& CHUNK_MAP_ALLOCATED
) != 0);
604 if ((mapbits
& CHUNK_MAP_LARGE
) == 0) {
606 ret
= (prof_ctx_t
*)(uintptr_t)1U;
608 arena_run_t
*run
= (arena_run_t
*)((uintptr_t)chunk
+
609 (uintptr_t)((pageind
- (mapbits
>> PAGE_SHIFT
)) <<
611 size_t binind
= arena_bin_index(chunk
->arena
, run
->bin
);
612 arena_bin_info_t
*bin_info
= &arena_bin_info
[binind
];
615 dassert(run
->magic
== ARENA_RUN_MAGIC
);
616 regind
= arena_run_regind(run
, bin_info
, ptr
);
617 ret
= *(prof_ctx_t
**)((uintptr_t)run
+
618 bin_info
->ctx0_offset
+ (regind
*
619 sizeof(prof_ctx_t
*)));
622 ret
= chunk
->map
[pageind
-map_bias
].prof_ctx
;
628 arena_prof_ctx_set(const void *ptr
, prof_ctx_t
*ctx
)
630 arena_chunk_t
*chunk
;
631 size_t pageind
, mapbits
;
634 assert(CHUNK_ADDR2BASE(ptr
) != ptr
);
636 chunk
= (arena_chunk_t
*)CHUNK_ADDR2BASE(ptr
);
637 pageind
= ((uintptr_t)ptr
- (uintptr_t)chunk
) >> PAGE_SHIFT
;
638 mapbits
= chunk
->map
[pageind
-map_bias
].bits
;
639 assert((mapbits
& CHUNK_MAP_ALLOCATED
) != 0);
640 if ((mapbits
& CHUNK_MAP_LARGE
) == 0) {
641 if (prof_promote
== false) {
642 arena_run_t
*run
= (arena_run_t
*)((uintptr_t)chunk
+
643 (uintptr_t)((pageind
- (mapbits
>> PAGE_SHIFT
)) <<
645 arena_bin_t
*bin
= run
->bin
;
647 arena_bin_info_t
*bin_info
;
650 dassert(run
->magic
== ARENA_RUN_MAGIC
);
651 binind
= arena_bin_index(chunk
->arena
, bin
);
652 bin_info
= &arena_bin_info
[binind
];
653 regind
= arena_run_regind(run
, bin_info
, ptr
);
655 *((prof_ctx_t
**)((uintptr_t)run
+ bin_info
->ctx0_offset
656 + (regind
* sizeof(prof_ctx_t
*)))) = ctx
;
658 assert((uintptr_t)ctx
== (uintptr_t)1U);
660 chunk
->map
[pageind
-map_bias
].prof_ctx
= ctx
;
665 arena_dalloc(arena_t
*arena
, arena_chunk_t
*chunk
, void *ptr
)
668 arena_chunk_map_t
*mapelm
;
670 assert(arena
!= NULL
);
671 dassert(arena
->magic
== ARENA_MAGIC
);
672 assert(chunk
->arena
== arena
);
674 assert(CHUNK_ADDR2BASE(ptr
) != ptr
);
676 pageind
= ((uintptr_t)ptr
- (uintptr_t)chunk
) >> PAGE_SHIFT
;
677 mapelm
= &chunk
->map
[pageind
-map_bias
];
678 assert((mapelm
->bits
& CHUNK_MAP_ALLOCATED
) != 0);
679 if ((mapelm
->bits
& CHUNK_MAP_LARGE
) == 0) {
680 /* Small allocation. */
681 #ifdef JEMALLOC_TCACHE
684 if ((tcache
= tcache_get()) != NULL
)
685 tcache_dalloc_small(tcache
, ptr
);
691 run
= (arena_run_t
*)((uintptr_t)chunk
+
692 (uintptr_t)((pageind
- (mapelm
->bits
>>
693 PAGE_SHIFT
)) << PAGE_SHIFT
));
694 dassert(run
->magic
== ARENA_RUN_MAGIC
);
696 #ifdef JEMALLOC_DEBUG
698 size_t binind
= arena_bin_index(arena
, bin
);
699 arena_bin_info_t
*bin_info
=
700 &arena_bin_info
[binind
];
701 assert(((uintptr_t)ptr
- ((uintptr_t)run
+
702 (uintptr_t)bin_info
->reg0_offset
)) %
703 bin_info
->reg_size
== 0);
706 malloc_mutex_lock(&bin
->lock
);
707 arena_dalloc_bin(arena
, chunk
, ptr
, mapelm
);
708 malloc_mutex_unlock(&bin
->lock
);
709 #ifdef JEMALLOC_TCACHE
713 #ifdef JEMALLOC_TCACHE
714 size_t size
= mapelm
->bits
& ~PAGE_MASK
;
716 assert(((uintptr_t)ptr
& PAGE_MASK
) == 0);
717 if (size
<= tcache_maxclass
) {
720 if ((tcache
= tcache_get()) != NULL
)
721 tcache_dalloc_large(tcache
, ptr
, size
);
723 malloc_mutex_lock(&arena
->lock
);
724 arena_dalloc_large(arena
, chunk
, ptr
);
725 malloc_mutex_unlock(&arena
->lock
);
728 malloc_mutex_lock(&arena
->lock
);
729 arena_dalloc_large(arena
, chunk
, ptr
);
730 malloc_mutex_unlock(&arena
->lock
);
733 assert(((uintptr_t)ptr
& PAGE_MASK
) == 0);
734 malloc_mutex_lock(&arena
->lock
);
735 arena_dalloc_large(arena
, chunk
, ptr
);
736 malloc_mutex_unlock(&arena
->lock
);
742 #endif /* JEMALLOC_H_INLINES */
743 /******************************************************************************/