Rizin
unix-like reverse engineering framework and cli tools
jemalloc_internal.h
Go to the documentation of this file.
1 #ifndef JEMALLOC_INTERNAL_H
2 #define JEMALLOC_INTERNAL_H
3 
6 
7 #ifdef JEMALLOC_UTRACE
8 #include <sys/ktrace.h>
9 #endif
10 
11 #define JEMALLOC_NO_DEMANGLE
12 #ifdef JEMALLOC_JET
13 # define JEMALLOC_N(n) jet_##n
14 # include "public_namespace.h"
15 # define JEMALLOC_NO_RENAME
16 # include "../jemalloc.h"
17 # undef JEMALLOC_NO_RENAME
18 #else
19 # define JEMALLOC_N(n) je_##n
20 # include "../jemalloc.h"
21 #endif
22 #include "private_namespace.h"
23 
24 static const bool config_debug =
25 #ifdef JEMALLOC_DEBUG
26  true
27 #else
28  false
29 #endif
30  ;
31 static const bool have_dss =
32 #ifdef JEMALLOC_DSS
33  true
34 #else
35  false
36 #endif
37  ;
38 static const bool config_fill =
39 #ifdef JEMALLOC_FILL
40  true
41 #else
42  false
43 #endif
44  ;
45 static const bool config_lazy_lock =
46 #ifdef JEMALLOC_LAZY_LOCK
47  true
48 #else
49  false
50 #endif
51  ;
52 static const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF;
53 static const bool config_prof =
54 #ifdef JEMALLOC_PROF
55  true
56 #else
57  false
58 #endif
59  ;
60 static const bool config_prof_libgcc =
61 #ifdef JEMALLOC_PROF_LIBGCC
62  true
63 #else
64  false
65 #endif
66  ;
67 static const bool config_prof_libunwind =
68 #ifdef JEMALLOC_PROF_LIBUNWIND
69  true
70 #else
71  false
72 #endif
73  ;
74 static const bool maps_coalesce =
75 #ifdef JEMALLOC_MAPS_COALESCE
76  true
77 #else
78  false
79 #endif
80  ;
81 static const bool config_munmap =
82 #ifdef JEMALLOC_MUNMAP
83  true
84 #else
85  false
86 #endif
87  ;
88 static const bool config_stats =
89 #ifdef JEMALLOC_STATS
90  true
91 #else
92  false
93 #endif
94  ;
95 static const bool config_tcache =
96 #ifdef JEMALLOC_TCACHE
97  true
98 #else
99  false
100 #endif
101  ;
102 static const bool config_thp =
103 #ifdef JEMALLOC_THP
104  true
105 #else
106  false
107 #endif
108  ;
109 static const bool config_tls =
110 #ifdef JEMALLOC_TLS
111  true
112 #else
113  false
114 #endif
115  ;
116 static const bool config_utrace =
117 #ifdef JEMALLOC_UTRACE
118  true
119 #else
120  false
121 #endif
122  ;
123 static const bool config_valgrind =
124 #ifdef JEMALLOC_VALGRIND
125  true
126 #else
127  false
128 #endif
129  ;
130 static const bool config_xmalloc =
131 #ifdef JEMALLOC_XMALLOC
132  true
133 #else
134  false
135 #endif
136  ;
137 static const bool config_ivsalloc =
138 #ifdef JEMALLOC_IVSALLOC
139  true
140 #else
141  false
142 #endif
143  ;
144 static const bool config_cache_oblivious =
145 #ifdef JEMALLOC_CACHE_OBLIVIOUS
146  true
147 #else
148  false
149 #endif
150  ;
151 
152 #ifdef JEMALLOC_ATOMIC9
153 #include <machine/atomic.h>
154 #endif
155 
156 #if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN))
157 #include <libkern/OSAtomic.h>
158 #endif
159 
160 #ifdef JEMALLOC_ZONE
161 #include <mach/mach_error.h>
162 #include <mach/mach_init.h>
163 #include <mach/vm_map.h>
164 #endif
165 
166 #include "ph.h"
167 #ifndef __PGI
168 #define RB_COMPACT
169 #endif
170 #include "rb.h"
171 #include "qr.h"
172 #include "ql.h"
173 
174 /*
175  * jemalloc can conceptually be broken into components (arena, tcache, etc.),
176  * but there are circular dependencies that cannot be broken without
177  * substantial performance degradation. In order to reduce the effect on
178  * visual code flow, read the header files in multiple passes, with one of the
179  * following cpp variables defined during each pass:
180  *
181  * JEMALLOC_H_TYPES : Preprocessor-defined constants and psuedo-opaque data
182  * types.
183  * JEMALLOC_H_STRUCTS : Data structures.
184  * JEMALLOC_H_EXTERNS : Extern data declarations and function prototypes.
185  * JEMALLOC_H_INLINES : Inline functions.
186  */
187 /******************************************************************************/
188 #define JEMALLOC_H_TYPES
189 
191 
192 /* Page size index type. */
193 typedef unsigned pszind_t;
194 
195 /* Size class index type. */
196 typedef unsigned szind_t;
197 
198 /*
199  * Flags bits:
200  *
201  * a: arena
202  * t: tcache
203  * 0: unused
204  * z: zero
205  * n: alignment
206  *
207  * aaaaaaaa aaaatttt tttttttt 0znnnnnn
208  */
209 #define MALLOCX_ARENA_MASK ((int)~0xfffff)
210 #define MALLOCX_ARENA_MAX 0xffe
211 #define MALLOCX_TCACHE_MASK ((int)~0xfff000ffU)
212 #define MALLOCX_TCACHE_MAX 0xffd
213 #define MALLOCX_LG_ALIGN_MASK ((int)0x3f)
214 /* Use MALLOCX_ALIGN_GET() if alignment may not be specified in flags. */
215 #define MALLOCX_ALIGN_GET_SPECIFIED(flags) \
216  (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK))
217 #define MALLOCX_ALIGN_GET(flags) \
218  (MALLOCX_ALIGN_GET_SPECIFIED(flags) & (SIZE_T_MAX-1))
219 #define MALLOCX_ZERO_GET(flags) \
220  ((bool)(flags & MALLOCX_ZERO))
221 
222 #define MALLOCX_TCACHE_GET(flags) \
223  (((unsigned)((flags & MALLOCX_TCACHE_MASK) >> 8)) - 2)
224 #define MALLOCX_ARENA_GET(flags) \
225  (((unsigned)(((unsigned)flags) >> 20)) - 1)
226 
227 /* Smallest size class to support. */
228 #define TINY_MIN (1U << LG_TINY_MIN)
229 
230 /*
231  * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size
232  * classes).
233  */
234 #ifndef LG_QUANTUM
235 # if (defined(__i386__) || defined(_M_IX86))
236 # define LG_QUANTUM 4
237 # endif
238 # ifdef __ia64__
239 # define LG_QUANTUM 4
240 # endif
241 # ifdef __alpha__
242 # define LG_QUANTUM 4
243 # endif
244 # if (defined(__sparc64__) || defined(__sparcv9) || defined(__sparc_v9__))
245 # define LG_QUANTUM 4
246 # endif
247 # if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))
248 # define LG_QUANTUM 4
249 # endif
250 # ifdef __arm__
251 # define LG_QUANTUM 3
252 # endif
253 # ifdef __aarch64__
254 # define LG_QUANTUM 4
255 # endif
256 # ifdef __hppa__
257 # define LG_QUANTUM 4
258 # endif
259 # ifdef __m68k__
260 # define LG_QUANTUM 3
261 # endif
262 # ifdef __mips__
263 # define LG_QUANTUM 3
264 # endif
265 # ifdef __or1k__
266 # define LG_QUANTUM 3
267 # endif
268 # ifdef __powerpc__
269 # define LG_QUANTUM 4
270 # endif
271 # if defined(__riscv) || defined(__riscv__)
272 # define LG_QUANTUM 4
273 # endif
274 # ifdef __s390__
275 # define LG_QUANTUM 4
276 # endif
277 # ifdef __SH4__
278 # define LG_QUANTUM 4
279 # endif
280 # ifdef __tile__
281 # define LG_QUANTUM 4
282 # endif
283 # ifdef __le32__
284 # define LG_QUANTUM 4
285 # endif
286 # ifndef LG_QUANTUM
287 # error "Unknown minimum alignment for architecture; specify via "
288  "--with-lg-quantum"
289 # endif
290 #endif
291 
292 #define QUANTUM ((size_t)(1U << LG_QUANTUM))
293 #define QUANTUM_MASK (QUANTUM - 1)
294 
295 /* Return the smallest quantum multiple that is >= a. */
296 #define QUANTUM_CEILING(a) \
297  (((a) + QUANTUM_MASK) & ~QUANTUM_MASK)
298 
299 #define LONG ((size_t)(1U << LG_SIZEOF_LONG))
300 #define LONG_MASK (LONG - 1)
301 
302 /* Return the smallest long multiple that is >= a. */
303 #define LONG_CEILING(a) \
304  (((a) + LONG_MASK) & ~LONG_MASK)
305 
306 #define SIZEOF_PTR (1U << LG_SIZEOF_PTR)
307 #define PTR_MASK (SIZEOF_PTR - 1)
308 
309 /* Return the smallest (void *) multiple that is >= a. */
310 #define PTR_CEILING(a) \
311  (((a) + PTR_MASK) & ~PTR_MASK)
312 
313 /*
314  * Maximum size of L1 cache line. This is used to avoid cache line aliasing.
315  * In addition, this controls the spacing of cacheline-spaced size classes.
316  *
317  * CACHELINE cannot be based on LG_CACHELINE because __declspec(align()) can
318  * only handle raw constants.
319  */
320 #define LG_CACHELINE 6
321 #define CACHELINE 64
322 #define CACHELINE_MASK (CACHELINE - 1)
323 
324 /* Return the smallest cacheline multiple that is >= s. */
325 #define CACHELINE_CEILING(s) \
326  (((s) + CACHELINE_MASK) & ~CACHELINE_MASK)
327 
328 /* Page size. LG_PAGE is determined by the configure script. */
329 #ifdef PAGE_MASK
330 # undef PAGE_MASK
331 #endif
332 #define PAGE ((size_t)(1U << LG_PAGE))
333 #define PAGE_MASK ((size_t)(PAGE - 1))
334 
335 /* Return the page base address for the page containing address a. */
336 #define PAGE_ADDR2BASE(a) \
337  ((void *)((uintptr_t)(a) & ~PAGE_MASK))
338 
339 /* Return the smallest pagesize multiple that is >= s. */
340 #define PAGE_CEILING(s) \
341  (((s) + PAGE_MASK) & ~PAGE_MASK)
342 
343 /* Return the nearest aligned address at or below a. */
344 #define ALIGNMENT_ADDR2BASE(a, alignment) \
345  ((void *)((uintptr_t)(a) & ((~(alignment)) + 1)))
346 
347 /* Return the offset between a and the nearest aligned address at or below a. */
348 #define ALIGNMENT_ADDR2OFFSET(a, alignment) \
349  ((size_t)((uintptr_t)(a) & (alignment - 1)))
350 
351 /* Return the smallest alignment multiple that is >= s. */
352 #define ALIGNMENT_CEILING(s, alignment) \
353  (((s) + (alignment - 1)) & ((~(alignment)) + 1))
354 
355 /* Declare a variable-length array. */
356 #if __STDC_VERSION__ < 199901L
357 # ifdef _MSC_VER
358 # include <malloc.h>
359 # define alloca _alloca
360 # else
361 # include <stdlib.h>
362 # endif
363 # define VARIABLE_ARRAY(type, name, count) \
364  type *name = alloca(sizeof(type) * (count))
365 #else
366 # define VARIABLE_ARRAY(type, name, count) type name[(count)]
367 #endif
368 
369 #include "nstime.h"
370 #include "valgrind.h"
371 #include "util.h"
372 #include "atomic.h"
373 #include "spin.h"
374 #include "prng.h"
375 #include "ticker.h"
376 #include "ckh.h"
377 #include "size_classes.h"
378 #include "smoothstep.h"
379 #include "stats.h"
380 #include "ctl.h"
381 #include "witness.h"
382 #include "mutex.h"
383 #include "tsd.h"
384 #include "mb.h"
385 #include "extent.h"
386 #include "arena.h"
387 #include "bitmap.h"
388 #include "base.h"
389 #include "rtree.h"
390 #include "pages.h"
391 #include "chunk.h"
392 #include "huge.h"
393 #include "tcache.h"
394 #include "hash.h"
395 #include "quarantine.h"
396 #include "prof.h"
397 
398 #undef JEMALLOC_H_TYPES
399 /******************************************************************************/
400 #define JEMALLOC_H_STRUCTS
401 
402 #include "nstime.h"
403 #include "valgrind.h"
404 #include "util.h"
405 #include "atomic.h"
406 #include "spin.h"
407 #include "prng.h"
408 #include "ticker.h"
409 #include "ckh.h"
410 #include "size_classes.h"
411 #include "smoothstep.h"
412 #include "stats.h"
413 #include "ctl.h"
414 #include "witness.h"
415 #include "mutex.h"
416 #include "mb.h"
417 #include "bitmap.h"
418 #define JEMALLOC_ARENA_STRUCTS_A
419 #include "arena.h"
420 #undef JEMALLOC_ARENA_STRUCTS_A
421 #include "extent.h"
422 #define JEMALLOC_ARENA_STRUCTS_B
423 #include "arena.h"
424 #undef JEMALLOC_ARENA_STRUCTS_B
425 #include "base.h"
426 #include "rtree.h"
427 #include "pages.h"
428 #include "chunk.h"
429 #include "huge.h"
430 #include "tcache.h"
431 #include "hash.h"
432 #include "quarantine.h"
433 #include "prof.h"
434 
435 #include "tsd.h"
436 
437 #undef JEMALLOC_H_STRUCTS
438 /******************************************************************************/
439 #define JEMALLOC_H_EXTERNS
440 
441 extern bool opt_abort;
442 extern const char *opt_junk;
443 extern bool opt_junk_alloc;
444 extern bool opt_junk_free;
445 extern size_t opt_quarantine;
446 extern bool opt_redzone;
447 extern bool opt_utrace;
448 extern bool opt_xmalloc;
449 extern bool opt_zero;
450 extern unsigned opt_narenas;
451 
452 extern bool in_valgrind;
453 
454 /* Number of CPUs. */
455 extern unsigned ncpus;
456 
457 /* Number of arenas used for automatic multiplexing of threads and arenas. */
458 extern unsigned narenas_auto;
459 
460 /*
461  * Arenas that are used to service external requests. Not all elements of the
462  * arenas array are necessarily used; arenas are created lazily as needed.
463  */
464 extern arena_t **arenas;
465 
466 /*
467  * pind2sz_tab encodes the same information as could be computed by
468  * pind2sz_compute().
469  */
470 extern size_t const pind2sz_tab[NPSIZES];
471 /*
472  * index2size_tab encodes the same information as could be computed (at
473  * unacceptable cost in some code paths) by index2size_compute().
474  */
475 extern size_t const index2size_tab[NSIZES];
476 /*
477  * size2index_tab is a compact lookup table that rounds request sizes up to
478  * size classes. In order to reduce cache footprint, the table is compressed,
479  * and all accesses are via size2index().
480  */
481 extern uint8_t const size2index_tab[];
482 
483 arena_t *a0get(void);
484 void *a0malloc(size_t size);
485 void a0dalloc(void *ptr);
486 void *bootstrap_malloc(size_t size);
487 void *bootstrap_calloc(size_t num, size_t size);
488 void bootstrap_free(void *ptr);
489 unsigned narenas_total_get(void);
490 arena_t *arena_init(tsdn_t *tsdn, unsigned ind);
491 arena_tdata_t *arena_tdata_get_hard(tsd_t *tsd, unsigned ind);
492 arena_t *arena_choose_hard(tsd_t *tsd, bool internal);
493 void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind);
494 void thread_allocated_cleanup(tsd_t *tsd);
495 void thread_deallocated_cleanup(tsd_t *tsd);
496 void iarena_cleanup(tsd_t *tsd);
497 void arena_cleanup(tsd_t *tsd);
498 void arenas_tdata_cleanup(tsd_t *tsd);
499 void narenas_tdata_cleanup(tsd_t *tsd);
501 void jemalloc_prefork(void);
504 
505 #include "nstime.h"
506 #include "valgrind.h"
507 #include "util.h"
508 #include "atomic.h"
509 #include "spin.h"
510 #include "prng.h"
511 #include "ticker.h"
512 #include "ckh.h"
513 #include "size_classes.h"
514 #include "smoothstep.h"
515 #include "stats.h"
516 #include "ctl.h"
517 #include "witness.h"
518 #include "mutex.h"
519 #include "mb.h"
520 #include "bitmap.h"
521 #include "extent.h"
522 #include "arena.h"
523 #include "base.h"
524 #include "rtree.h"
525 #include "pages.h"
526 #include "chunk.h"
527 #include "huge.h"
528 #include "tcache.h"
529 #include "hash.h"
530 #include "quarantine.h"
531 #include "prof.h"
532 #include "tsd.h"
533 
534 #undef JEMALLOC_H_EXTERNS
535 /******************************************************************************/
536 #define JEMALLOC_H_INLINES
537 
538 #include "nstime.h"
539 #include "valgrind.h"
540 #include "util.h"
541 #include "atomic.h"
542 #include "spin.h"
543 #include "prng.h"
544 #include "ticker.h"
545 #include "ckh.h"
546 #include "size_classes.h"
547 #include "smoothstep.h"
548 #include "stats.h"
549 #include "ctl.h"
550 #include "tsd.h"
551 #include "witness.h"
552 #include "mutex.h"
553 #include "mb.h"
554 #include "extent.h"
555 #include "base.h"
556 #include "rtree.h"
557 #include "pages.h"
558 #include "chunk.h"
559 #include "huge.h"
560 
561 #ifndef JEMALLOC_ENABLE_INLINE
562 pszind_t psz2ind(size_t psz);
565 size_t pind2sz(pszind_t pind);
566 size_t psz2u(size_t psz);
572 size_t index2size(szind_t index);
573 size_t s2u_compute(size_t size);
574 size_t s2u_lookup(size_t size);
575 size_t s2u(size_t size);
576 size_t sa2u(size_t size, size_t alignment);
577 arena_t *arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal);
578 arena_t *arena_choose(tsd_t *tsd, arena_t *arena);
579 arena_t *arena_ichoose(tsd_t *tsd, arena_t *arena);
580 arena_tdata_t *arena_tdata_get(tsd_t *tsd, unsigned ind,
581  bool refresh_if_missing);
582 arena_t *arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing);
583 ticker_t *decay_ticker_get(tsd_t *tsd, unsigned ind);
584 #endif
585 
586 
587 #include "bitmap.h"
588 /*
589  * Include portions of arena.h interleaved with tcache.h in order to resolve
590  * circular dependencies.
591  */
592 #define JEMALLOC_ARENA_INLINE_A
593 #include "arena.h"
594 #undef JEMALLOC_ARENA_INLINE_A
595 #include "tcache.h"
596 #define JEMALLOC_ARENA_INLINE_B
597 #include "arena.h"
598 #undef JEMALLOC_ARENA_INLINE_B
599 #include "hash.h"
600 #include "quarantine.h"
601 
602 #endif /* JEMALLOC_INTERNAL_H */
voidpf void uLong size
Definition: ioapi.h:138
arena_t * arena_ichoose(tsd_t *tsd, arena_t *arena)
static const bool config_utrace
bool in_valgrind
void * a0malloc(size_t size)
unsigned szind_t
static const bool config_stats
static const bool config_prof_libgcc
static const bool config_ivsalloc
size_t pind2sz_compute(pszind_t pind)
static const bool config_valgrind
static const bool config_tls
ticker_t * decay_ticker_get(tsd_t *tsd, unsigned ind)
arena_t * arena_init(tsdn_t *tsdn, unsigned ind)
size_t opt_quarantine
szind_t size2index_compute(size_t size)
arena_t * arena_choose(tsd_t *tsd, arena_t *arena)
unsigned ncpus
szind_t size2index(size_t size)
void arenas_tdata_cleanup(tsd_t *tsd)
szind_t size2index_lookup(size_t size)
arena_t ** arenas
static const char *const config_malloc_conf
size_t pind2sz(pszind_t pind)
static const bool config_prof_libunwind
bool opt_redzone
size_t pind2sz_lookup(pszind_t pind)
size_t psz2u(size_t psz)
static const bool config_cache_oblivious
bool opt_utrace
unsigned narenas_total_get(void)
const char * opt_junk
size_t const index2size_tab[NSIZES]
size_t s2u_compute(size_t size)
bool opt_zero
static const bool have_dss
void iarena_cleanup(tsd_t *tsd)
static const bool config_prof
void narenas_tdata_cleanup(tsd_t *tsd)
unsigned pszind_t
void * bootstrap_calloc(size_t num, size_t size)
void thread_deallocated_cleanup(tsd_t *tsd)
bool opt_abort
static const bool config_tcache
arena_t * arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal)
void * bootstrap_malloc(size_t size)
static const bool config_thp
static const bool config_debug
size_t index2size_compute(szind_t index)
void jemalloc_postfork_child(void)
void arenas_tdata_bypass_cleanup(tsd_t *tsd)
void bootstrap_free(void *ptr)
pszind_t psz2ind(size_t psz)
unsigned opt_narenas
size_t s2u(size_t size)
bool opt_junk_alloc
size_t index2size(szind_t index)
static const bool maps_coalesce
static const bool config_munmap
arena_tdata_t * arena_tdata_get_hard(tsd_t *tsd, unsigned ind)
bool opt_xmalloc
size_t s2u_lookup(size_t size)
static const bool config_xmalloc
void jemalloc_prefork(void)
void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind)
void thread_allocated_cleanup(tsd_t *tsd)
void jemalloc_postfork_parent(void)
size_t sa2u(size_t size, size_t alignment)
arena_tdata_t * arena_tdata_get(tsd_t *tsd, unsigned ind, bool refresh_if_missing)
void arena_cleanup(tsd_t *tsd)
arena_t * arena_choose_hard(tsd_t *tsd, bool internal)
void a0dalloc(void *ptr)
static const bool config_fill
static const bool config_lazy_lock
unsigned narenas_auto
arena_t * a0get(void)
size_t index2size_lookup(szind_t index)
arena_t * arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing)
size_t const pind2sz_tab[NPSIZES]
uint8_t const size2index_tab[]
bool opt_junk_free
#define JEMALLOC_CONFIG_MALLOC_CONF
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
unsigned char uint8_t
Definition: sftypes.h:31
Definition: gun.c:81
Data types and functions used in many places in liblzma API.
Miscellaneous utility functions.