1 /*-
2  * Copyright (C) 2006-2010 Jason Evans <jasone@FreeBSD.org>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice(s), this list of conditions and the following disclaimer as
10  *    the first lines of this file unmodified other than the possible
11  *    addition of one or more copyright notices.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice(s), this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *******************************************************************************
30  *
31  * This allocator implementation is designed to provide scalable performance
32  * for multi-threaded programs on multi-processor systems.  The following
33  * features are included for this purpose:
34  *
35  *   + Multiple arenas are used if there are multiple CPUs, which reduces lock
36  *     contention and cache sloshing.
37  *
38  *   + Thread-specific caching is used if there are multiple threads, which
39  *     reduces the amount of locking.
40  *
41  *   + Cache line sharing between arenas is avoided for internal data
42  *     structures.
43  *
44  *   + Memory is managed in chunks and runs (chunks can be split into runs),
45  *     rather than as individual pages.  This provides a constant-time
46  *     mechanism for associating allocations with particular arenas.
47  *
48  * Allocation requests are rounded up to the nearest size class, and no record
49  * of the original request size is maintained.  Allocations are broken into
50  * categories according to size class.  Assuming runtime defaults, 4 KiB pages
51  * and a 16 byte quantum on a 32-bit system, the size classes in each category
52  * are as follows:
53  *
54  *   |========================================|
55  *   | Category | Subcategory      |     Size |
56  *   |========================================|
57  *   | Small    | Tiny             |        2 |
58  *   |          |                  |        4 |
59  *   |          |                  |        8 |
60  *   |          |------------------+----------|
61  *   |          | Quantum-spaced   |       16 |
62  *   |          |                  |       32 |
63  *   |          |                  |       48 |
64  *   |          |                  |      ... |
65  *   |          |                  |       96 |
66  *   |          |                  |      112 |
67  *   |          |                  |      128 |
68  *   |          |------------------+----------|
69  *   |          | Cacheline-spaced |      192 |
70  *   |          |                  |      256 |
71  *   |          |                  |      320 |
72  *   |          |                  |      384 |
73  *   |          |                  |      448 |
74  *   |          |                  |      512 |
75  *   |          |------------------+----------|
76  *   |          | Sub-page         |      760 |
77  *   |          |                  |     1024 |
78  *   |          |                  |     1280 |
79  *   |          |                  |      ... |
80  *   |          |                  |     3328 |
81  *   |          |                  |     3584 |
82  *   |          |                  |     3840 |
83  *   |========================================|
84  *   | Medium                      |    4 KiB |
85  *   |                             |    6 KiB |
86  *   |                             |    8 KiB |
87  *   |                             |      ... |
88  *   |                             |   28 KiB |
89  *   |                             |   30 KiB |
90  *   |                             |   32 KiB |
91  *   |========================================|
92  *   | Large                       |   36 KiB |
93  *   |                             |   40 KiB |
94  *   |                             |   44 KiB |
95  *   |                             |      ... |
96  *   |                             | 1012 KiB |
97  *   |                             | 1016 KiB |
98  *   |                             | 1020 KiB |
99  *   |========================================|
100  *   | Huge                        |    1 MiB |
101  *   |                             |    2 MiB |
102  *   |                             |    3 MiB |
103  *   |                             |      ... |
104  *   |========================================|
105  *
106  * Different mechanisms are used accoding to category:
107  *
108  *   Small/medium : Each size class is segregated into its own set of runs.
109  *                  Each run maintains a bitmap of which regions are
110  *                  free/allocated.
111  *
112  *   Large : Each allocation is backed by a dedicated run.  Metadata are stored
113  *           in the associated arena chunk header maps.
114  *
115  *   Huge : Each allocation is backed by a dedicated contiguous set of chunks.
116  *          Metadata are stored in a separate red-black tree.
117  *
118  *******************************************************************************
119  */
120 
121 /*
122  * MALLOC_PRODUCTION disables assertions and statistics gathering.  It also
123  * defaults the A and J runtime options to off.  These settings are appropriate
124  * for production systems.
125  */
126 #ifndef MALLOC_PRODUCTION
127 #define	MALLOC_PRODUCTION
128 #endif
129 
130 #ifndef MALLOC_PRODUCTION
131    /*
132     * MALLOC_DEBUG enables assertions and other sanity checks, and disables
133     * inline functions.
134     */
135 #  define MALLOC_DEBUG
136 
137    /* MALLOC_STATS enables statistics calculation. */
138 #  define MALLOC_STATS
139 #endif
140 
141 /*
142  * MALLOC_TINY enables support for tiny objects, which are smaller than one
143  * quantum.
144  */
145 #define	MALLOC_TINY
146 
147 /*
148  * MALLOC_TCACHE enables a thread-specific caching layer for small and medium
149  * objects.  This makes it possible to allocate/deallocate objects without any
150  * locking when the cache is in the steady state.
151  */
152 #define	MALLOC_TCACHE
153 
154 /*
155  * MALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage
156  * segment (DSS).  In an ideal world, this functionality would be completely
157  * unnecessary, but we are burdened by history and the lack of resource limits
158  * for anonymous mapped memory.
159  */
160 #define	MALLOC_DSS
161 
162 #include <sys/cdefs.h>
163 __FBSDID("$FreeBSD: stable/9/lib/libc/stdlib/malloc.c 252699 2013-07-04 14:26:42Z des $");
164 
165 #include "libc_private.h"
166 #ifdef MALLOC_DEBUG
167 #  define _LOCK_DEBUG
168 #endif
169 #include "spinlock.h"
170 #include "namespace.h"
171 #include <sys/mman.h>
172 #include <sys/param.h>
173 #include <sys/time.h>
174 #include <sys/types.h>
175 #include <sys/sysctl.h>
176 #include <sys/uio.h>
177 #include <sys/ktrace.h> /* Must come after several other sys/ includes. */
178 
179 #include <machine/cpufunc.h>
180 #include <machine/param.h>
181 #include <machine/vmparam.h>
182 
183 #include <errno.h>
184 #include <limits.h>
185 #include <link.h>
186 #include <pthread.h>
187 #include <sched.h>
188 #include <stdarg.h>
189 #include <stdbool.h>
190 #include <stdio.h>
191 #include <stdint.h>
192 #include <inttypes.h>
193 #include <stdlib.h>
194 #include <string.h>
195 #include <strings.h>
196 #include <unistd.h>
197 
198 #include "un-namespace.h"
199 
200 #include "libc_private.h"
201 
202 #define	RB_COMPACT
203 #include "rb.h"
204 #if (defined(MALLOC_TCACHE) && defined(MALLOC_STATS))
205 #include "qr.h"
206 #include "ql.h"
207 #endif
208 
209 #ifdef MALLOC_DEBUG
210    /* Disable inlining to make debugging easier. */
211 #  define inline
212 #endif
213 
214 /* Size of stack-allocated buffer passed to strerror_r(). */
215 #define	STRERROR_BUF		64
216 
217 /*
218  * Minimum alignment of allocations is 2^LG_QUANTUM bytes.
219  */
220 #ifdef __i386__
221 #  define LG_QUANTUM		4
222 #  define LG_SIZEOF_PTR		2
223 #  define CPU_SPINWAIT		__asm__ volatile("pause")
224 #  ifdef __clang__
225 #    define TLS_MODEL		/* clang does not support tls_model yet */
226 #  else
227 #    define TLS_MODEL		__attribute__((tls_model("initial-exec")))
228 #  endif
229 #endif
230 #ifdef __ia64__
231 #  define LG_QUANTUM		4
232 #  define LG_SIZEOF_PTR		3
233 #  define TLS_MODEL		/* default */
234 #endif
235 #ifdef __alpha__
236 #  define LG_QUANTUM		4
237 #  define LG_SIZEOF_PTR		3
238 #  define NO_TLS
239 #endif
240 #ifdef __sparc64__
241 #  define LG_QUANTUM		4
242 #  define LG_SIZEOF_PTR		3
243 #  define TLS_MODEL		__attribute__((tls_model("initial-exec")))
244 #endif
245 #ifdef __amd64__
246 #  define LG_QUANTUM		4
247 #  define LG_SIZEOF_PTR		3
248 #  define CPU_SPINWAIT		__asm__ volatile("pause")
249 #  ifdef __clang__
250 #    define TLS_MODEL		/* clang does not support tls_model yet */
251 #  else
252 #    define TLS_MODEL		__attribute__((tls_model("initial-exec")))
253 #  endif
254 #endif
255 #ifdef __arm__
256 #  define LG_QUANTUM		3
257 #  define LG_SIZEOF_PTR		2
258 #  define NO_TLS
259 #endif
260 #ifdef __mips__
261 #  define LG_QUANTUM		3
262 #  define LG_SIZEOF_PTR		2
263 #  define NO_TLS
264 #endif
265 #ifdef __powerpc64__
266 #  define LG_QUANTUM		4
267 #  define LG_SIZEOF_PTR		3
268 #  define TLS_MODEL		/* default */
269 #elif defined(__powerpc__)
270 #  define LG_QUANTUM		4
271 #  define LG_SIZEOF_PTR		2
272 #  define TLS_MODEL		/* default */
273 #endif
274 #ifdef __s390x__
275 #  define LG_QUANTUM		4
276 #endif
277 
278 #define	QUANTUM			((size_t)(1U << LG_QUANTUM))
279 #define	QUANTUM_MASK		(QUANTUM - 1)
280 
281 #define	SIZEOF_PTR		(1U << LG_SIZEOF_PTR)
282 
283 /* sizeof(int) == (1U << LG_SIZEOF_INT). */
284 #ifndef LG_SIZEOF_INT
285 #  define LG_SIZEOF_INT	2
286 #endif
287 
288 /* We can't use TLS in non-PIC programs, since TLS relies on loader magic. */
289 #if (!defined(PIC) && !defined(NO_TLS))
290 #  define NO_TLS
291 #endif
292 
293 #ifdef NO_TLS
294    /* MALLOC_TCACHE requires TLS. */
295 #  ifdef MALLOC_TCACHE
296 #    undef MALLOC_TCACHE
297 #  endif
298 #endif
299 
300 /*
301  * Size and alignment of memory chunks that are allocated by the OS's virtual
302  * memory system.
303  */
304 #define	LG_CHUNK_DEFAULT	22
305 
306 /*
307  * The minimum ratio of active:dirty pages per arena is computed as:
308  *
309  *   (nactive >> opt_lg_dirty_mult) >= ndirty
310  *
311  * So, supposing that opt_lg_dirty_mult is 5, there can be no less than 32
312  * times as many active pages as dirty pages.
313  */
314 #define	LG_DIRTY_MULT_DEFAULT	5
315 
316 /*
317  * Maximum size of L1 cache line.  This is used to avoid cache line aliasing.
318  * In addition, this controls the spacing of cacheline-spaced size classes.
319  */
320 #define	LG_CACHELINE		6
321 #define	CACHELINE		((size_t)(1U << LG_CACHELINE))
322 #define	CACHELINE_MASK		(CACHELINE - 1)
323 
324 /*
325  * Subpages are an artificially designated partitioning of pages.  Their only
326  * purpose is to support subpage-spaced size classes.
327  *
328  * There must be at least 4 subpages per page, due to the way size classes are
329  * handled.
330  */
331 #define	LG_SUBPAGE		8
332 #define	SUBPAGE			((size_t)(1U << LG_SUBPAGE))
333 #define	SUBPAGE_MASK		(SUBPAGE - 1)
334 
335 #ifdef MALLOC_TINY
336    /* Smallest size class to support. */
337 #  define LG_TINY_MIN		1
338 #endif
339 
340 /*
341  * Maximum size class that is a multiple of the quantum, but not (necessarily)
342  * a power of 2.  Above this size, allocations are rounded up to the nearest
343  * power of 2.
344  */
345 #define	LG_QSPACE_MAX_DEFAULT	7
346 
347 /*
348  * Maximum size class that is a multiple of the cacheline, but not (necessarily)
349  * a power of 2.  Above this size, allocations are rounded up to the nearest
350  * power of 2.
351  */
352 #define	LG_CSPACE_MAX_DEFAULT	9
353 
354 /*
355  * Maximum medium size class.  This must not be more than 1/4 of a chunk
356  * (LG_MEDIUM_MAX_DEFAULT <= LG_CHUNK_DEFAULT - 2).
357  */
358 #define	LG_MEDIUM_MAX_DEFAULT	15
359 
360 /*
361  * RUN_MAX_OVRHD indicates maximum desired run header overhead.  Runs are sized
362  * as small as possible such that this setting is still honored, without
363  * violating other constraints.  The goal is to make runs as small as possible
364  * without exceeding a per run external fragmentation threshold.
365  *
366  * We use binary fixed point math for overhead computations, where the binary
367  * point is implicitly RUN_BFP bits to the left.
368  *
369  * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
370  * honored for some/all object sizes, since there is one bit of header overhead
371  * per object (plus a constant).  This constraint is relaxed (ignored) for runs
372  * that are so small that the per-region overhead is greater than:
373  *
374  *   (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
375  */
376 #define	RUN_BFP			12
377 /*                                    \/   Implicit binary fixed point. */
378 #define	RUN_MAX_OVRHD		0x0000003dU
379 #define	RUN_MAX_OVRHD_RELAX	0x00001800U
380 
381 /* Put a cap on small object run size.  This overrides RUN_MAX_OVRHD. */
382 #define	RUN_MAX_SMALL							\
383 	(arena_maxclass <= (1U << (CHUNK_MAP_LG_PG_RANGE + PAGE_SHIFT))	\
384 	    ? arena_maxclass : (1U << (CHUNK_MAP_LG_PG_RANGE +		\
385 	    PAGE_SHIFT)))
386 
387 /*
388  * Hyper-threaded CPUs may need a special instruction inside spin loops in
389  * order to yield to another virtual CPU.  If no such instruction is defined
390  * above, make CPU_SPINWAIT a no-op.
391  */
392 #ifndef CPU_SPINWAIT
393 #  define CPU_SPINWAIT
394 #endif
395 
396 /*
397  * Adaptive spinning must eventually switch to blocking, in order to avoid the
398  * potential for priority inversion deadlock.  Backing off past a certain point
399  * can actually waste time.
400  */
401 #define	LG_SPIN_LIMIT		11
402 
403 #ifdef MALLOC_TCACHE
404    /*
405     * Default number of cache slots for each bin in the thread cache (0:
406     * disabled).
407     */
408 #  define LG_TCACHE_NSLOTS_DEFAULT	7
409    /*
410     * (1U << opt_lg_tcache_gc_sweep) is the approximate number of
411     * allocation events between full GC sweeps (-1: disabled).  Integer
412     * rounding may cause the actual number to be slightly higher, since GC is
413     * performed incrementally.
414     */
415 #  define LG_TCACHE_GC_SWEEP_DEFAULT	13
416 #endif
417 
418 /******************************************************************************/
419 
420 /*
421  * Mutexes based on spinlocks.  We can't use normal pthread spinlocks in all
422  * places, because they require malloc()ed memory, which causes bootstrapping
423  * issues in some cases.
424  */
425 typedef struct {
426 	spinlock_t	lock;
427 } malloc_mutex_t;
428 
429 /* Set to true once the allocator has been initialized. */
430 static bool malloc_initialized = false;
431 
432 /* Used to avoid initialization races. */
433 static malloc_mutex_t init_lock = {_SPINLOCK_INITIALIZER};
434 
435 /******************************************************************************/
436 /*
437  * Statistics data structures.
438  */
439 
440 #ifdef MALLOC_STATS
441 
442 #ifdef MALLOC_TCACHE
443 typedef struct tcache_bin_stats_s tcache_bin_stats_t;
444 struct tcache_bin_stats_s {
445 	/*
446 	 * Number of allocation requests that corresponded to the size of this
447 	 * bin.
448 	 */
449 	uint64_t	nrequests;
450 };
451 #endif
452 
453 typedef struct malloc_bin_stats_s malloc_bin_stats_t;
454 struct malloc_bin_stats_s {
455 	/*
456 	 * Number of allocation requests that corresponded to the size of this
457 	 * bin.
458 	 */
459 	uint64_t	nrequests;
460 
461 #ifdef MALLOC_TCACHE
462 	/* Number of tcache fills from this bin. */
463 	uint64_t	nfills;
464 
465 	/* Number of tcache flushes to this bin. */
466 	uint64_t	nflushes;
467 #endif
468 
469 	/* Total number of runs created for this bin's size class. */
470 	uint64_t	nruns;
471 
472 	/*
473 	 * Total number of runs reused by extracting them from the runs tree for
474 	 * this bin's size class.
475 	 */
476 	uint64_t	reruns;
477 
478 	/* High-water mark for this bin. */
479 	size_t		highruns;
480 
481 	/* Current number of runs in this bin. */
482 	size_t		curruns;
483 };
484 
485 typedef struct malloc_large_stats_s malloc_large_stats_t;
486 struct malloc_large_stats_s {
487 	/*
488 	 * Number of allocation requests that corresponded to this size class.
489 	 */
490 	uint64_t	nrequests;
491 
492 	/* High-water mark for this size class. */
493 	size_t		highruns;
494 
495 	/* Current number of runs of this size class. */
496 	size_t		curruns;
497 };
498 
499 typedef struct arena_stats_s arena_stats_t;
500 struct arena_stats_s {
501 	/* Number of bytes currently mapped. */
502 	size_t		mapped;
503 
504 	/*
505 	 * Total number of purge sweeps, total number of madvise calls made,
506 	 * and total pages purged in order to keep dirty unused memory under
507 	 * control.
508 	 */
509 	uint64_t	npurge;
510 	uint64_t	nmadvise;
511 	uint64_t	purged;
512 
513 	/* Per-size-category statistics. */
514 	size_t		allocated_small;
515 	uint64_t	nmalloc_small;
516 	uint64_t	ndalloc_small;
517 
518 	size_t		allocated_medium;
519 	uint64_t	nmalloc_medium;
520 	uint64_t	ndalloc_medium;
521 
522 	size_t		allocated_large;
523 	uint64_t	nmalloc_large;
524 	uint64_t	ndalloc_large;
525 
526 	/*
527 	 * One element for each possible size class, including sizes that
528 	 * overlap with bin size classes.  This is necessary because ipalloc()
529 	 * sometimes has to use such large objects in order to assure proper
530 	 * alignment.
531 	 */
532 	malloc_large_stats_t	*lstats;
533 };
534 
535 typedef struct chunk_stats_s chunk_stats_t;
536 struct chunk_stats_s {
537 	/* Number of chunks that were allocated. */
538 	uint64_t	nchunks;
539 
540 	/* High-water mark for number of chunks allocated. */
541 	size_t		highchunks;
542 
543 	/*
544 	 * Current number of chunks allocated.  This value isn't maintained for
545 	 * any other purpose, so keep track of it in order to be able to set
546 	 * highchunks.
547 	 */
548 	size_t		curchunks;
549 };
550 
551 #endif /* #ifdef MALLOC_STATS */
552 
553 /******************************************************************************/
554 /*
555  * Extent data structures.
556  */
557 
558 /* Tree of extents. */
559 typedef struct extent_node_s extent_node_t;
560 struct extent_node_s {
561 #ifdef MALLOC_DSS
562 	/* Linkage for the size/address-ordered tree. */
563 	rb_node(extent_node_t) link_szad;
564 #endif
565 
566 	/* Linkage for the address-ordered tree. */
567 	rb_node(extent_node_t) link_ad;
568 
569 	/* Pointer to the extent that this tree node is responsible for. */
570 	void	*addr;
571 
572 	/* Total region size. */
573 	size_t	size;
574 };
575 typedef rb_tree(extent_node_t) extent_tree_t;
576 
577 /******************************************************************************/
578 /*
579  * Arena data structures.
580  */
581 
582 typedef struct arena_s arena_t;
583 typedef struct arena_bin_s arena_bin_t;
584 
585 /* Each element of the chunk map corresponds to one page within the chunk. */
586 typedef struct arena_chunk_map_s arena_chunk_map_t;
587 struct arena_chunk_map_s {
588 	/*
589 	 * Linkage for run trees.  There are two disjoint uses:
590 	 *
591 	 * 1) arena_t's runs_avail tree.
592 	 * 2) arena_run_t conceptually uses this linkage for in-use non-full
593 	 *    runs, rather than directly embedding linkage.
594 	 */
595 	rb_node(arena_chunk_map_t)	link;
596 
597 	/*
598 	 * Run address (or size) and various flags are stored together.  The bit
599 	 * layout looks like (assuming 32-bit system):
600 	 *
601 	 *   ???????? ???????? ????cccc ccccdzla
602 	 *
603 	 * ? : Unallocated: Run address for first/last pages, unset for internal
604 	 *                  pages.
605 	 *     Small/medium: Don't care.
606 	 *     Large: Run size for first page, unset for trailing pages.
607 	 * - : Unused.
608 	 * c : refcount (could overflow for PAGE_SIZE >= 128 KiB)
609 	 * d : dirty?
610 	 * z : zeroed?
611 	 * l : large?
612 	 * a : allocated?
613 	 *
614 	 * Following are example bit patterns for the three types of runs.
615 	 *
616 	 * p : run page offset
617 	 * s : run size
618 	 * x : don't care
619 	 * - : 0
620 	 * [dzla] : bit set
621 	 *
622 	 *   Unallocated:
623 	 *     ssssssss ssssssss ssss---- --------
624 	 *     xxxxxxxx xxxxxxxx xxxx---- ----d---
625 	 *     ssssssss ssssssss ssss---- -----z--
626 	 *
627 	 *   Small/medium:
628 	 *     pppppppp ppppcccc cccccccc cccc---a
629 	 *     pppppppp ppppcccc cccccccc cccc---a
630 	 *     pppppppp ppppcccc cccccccc cccc---a
631 	 *
632 	 *   Large:
633 	 *     ssssssss ssssssss ssss---- ------la
634 	 *     -------- -------- -------- ------la
635 	 *     -------- -------- -------- ------la
636 	 */
637 	size_t				bits;
638 #define	CHUNK_MAP_PG_MASK	((size_t)0xfff00000U)
639 #define	CHUNK_MAP_PG_SHIFT	20
640 #define	CHUNK_MAP_LG_PG_RANGE	12
641 
642 #define	CHUNK_MAP_RC_MASK	((size_t)0xffff0U)
643 #define	CHUNK_MAP_RC_ONE	((size_t)0x00010U)
644 
645 #define	CHUNK_MAP_FLAGS_MASK	((size_t)0xfU)
646 #define	CHUNK_MAP_DIRTY		((size_t)0x8U)
647 #define	CHUNK_MAP_ZEROED	((size_t)0x4U)
648 #define	CHUNK_MAP_LARGE		((size_t)0x2U)
649 #define	CHUNK_MAP_ALLOCATED	((size_t)0x1U)
650 #define	CHUNK_MAP_KEY		(CHUNK_MAP_DIRTY | CHUNK_MAP_ALLOCATED)
651 };
652 typedef rb_tree(arena_chunk_map_t) arena_avail_tree_t;
653 typedef rb_tree(arena_chunk_map_t) arena_run_tree_t;
654 
655 /* Arena chunk header. */
656 typedef struct arena_chunk_s arena_chunk_t;
657 struct arena_chunk_s {
658 	/* Arena that owns the chunk. */
659 	arena_t		*arena;
660 
661 	/* Linkage for the arena's chunks_dirty tree. */
662 	rb_node(arena_chunk_t) link_dirty;
663 
664 	/*
665 	 * True if the chunk is currently in the chunks_dirty tree, due to
666 	 * having at some point contained one or more dirty pages.  Removal
667 	 * from chunks_dirty is lazy, so (dirtied && ndirty == 0) is possible.
668 	 */
669 	bool		dirtied;
670 
671 	/* Number of dirty pages. */
672 	size_t		ndirty;
673 
674 	/* Map of pages within chunk that keeps track of free/large/small. */
675 	arena_chunk_map_t map[1]; /* Dynamically sized. */
676 };
677 typedef rb_tree(arena_chunk_t) arena_chunk_tree_t;
678 
679 typedef struct arena_run_s arena_run_t;
680 struct arena_run_s {
681 #ifdef MALLOC_DEBUG
682 	uint32_t	magic;
683 #  define ARENA_RUN_MAGIC 0x384adf93
684 #endif
685 
686 	/* Bin this run is associated with. */
687 	arena_bin_t	*bin;
688 
689 	/* Index of first element that might have a free region. */
690 	unsigned	regs_minelm;
691 
692 	/* Number of free regions in run. */
693 	unsigned	nfree;
694 
695 	/* Bitmask of in-use regions (0: in use, 1: free). */
696 	unsigned	regs_mask[1]; /* Dynamically sized. */
697 };
698 
699 struct arena_bin_s {
700 	/*
701 	 * Current run being used to service allocations of this bin's size
702 	 * class.
703 	 */
704 	arena_run_t	*runcur;
705 
706 	/*
707 	 * Tree of non-full runs.  This tree is used when looking for an
708 	 * existing run when runcur is no longer usable.  We choose the
709 	 * non-full run that is lowest in memory; this policy tends to keep
710 	 * objects packed well, and it can also help reduce the number of
711 	 * almost-empty chunks.
712 	 */
713 	arena_run_tree_t runs;
714 
715 	/* Size of regions in a run for this bin's size class. */
716 	size_t		reg_size;
717 
718 	/* Total size of a run for this bin's size class. */
719 	size_t		run_size;
720 
721 	/* Total number of regions in a run for this bin's size class. */
722 	uint32_t	nregs;
723 
724 	/* Number of elements in a run's regs_mask for this bin's size class. */
725 	uint32_t	regs_mask_nelms;
726 
727 	/* Offset of first region in a run for this bin's size class. */
728 	uint32_t	reg0_offset;
729 
730 #ifdef MALLOC_STATS
731 	/* Bin statistics. */
732 	malloc_bin_stats_t stats;
733 #endif
734 };
735 
736 #ifdef MALLOC_TCACHE
737 typedef struct tcache_s tcache_t;
738 #endif
739 
740 struct arena_s {
741 #ifdef MALLOC_DEBUG
742 	uint32_t		magic;
743 #  define ARENA_MAGIC 0x947d3d24
744 #endif
745 
746 	/* All operations on this arena require that lock be locked. */
747 	pthread_mutex_t		lock;
748 
749 #ifdef MALLOC_STATS
750 	arena_stats_t		stats;
751 #  ifdef MALLOC_TCACHE
752 	/*
753 	 * List of tcaches for extant threads associated with this arena.
754 	 * Stats from these are merged incrementally, and at exit.
755 	 */
756 	ql_head(tcache_t)	tcache_ql;
757 #  endif
758 #endif
759 
760 	/* Tree of dirty-page-containing chunks this arena manages. */
761 	arena_chunk_tree_t	chunks_dirty;
762 
763 	/*
764 	 * In order to avoid rapid chunk allocation/deallocation when an arena
765 	 * oscillates right on the cusp of needing a new chunk, cache the most
766 	 * recently freed chunk.  The spare is left in the arena's chunk trees
767 	 * until it is deleted.
768 	 *
769 	 * There is one spare chunk per arena, rather than one spare total, in
770 	 * order to avoid interactions between multiple threads that could make
771 	 * a single spare inadequate.
772 	 */
773 	arena_chunk_t		*spare;
774 
775 	/* Number of pages in active runs. */
776 	size_t			nactive;
777 
778 	/*
779 	 * Current count of pages within unused runs that are potentially
780 	 * dirty, and for which madvise(... MADV_FREE) has not been called.  By
781 	 * tracking this, we can institute a limit on how much dirty unused
782 	 * memory is mapped for each arena.
783 	 */
784 	size_t			ndirty;
785 
786 	/*
787 	 * Size/address-ordered tree of this arena's available runs.  This tree
788 	 * is used for first-best-fit run allocation.
789 	 */
790 	arena_avail_tree_t	runs_avail;
791 
792 	/*
793 	 * bins is used to store trees of free regions of the following sizes,
794 	 * assuming a 16-byte quantum, 4 KiB page size, and default
795 	 * MALLOC_OPTIONS.
796 	 *
797 	 *   bins[i] |   size |
798 	 *   --------+--------+
799 	 *        0  |      2 |
800 	 *        1  |      4 |
801 	 *        2  |      8 |
802 	 *   --------+--------+
803 	 *        3  |     16 |
804 	 *        4  |     32 |
805 	 *        5  |     48 |
806 	 *           :        :
807 	 *        8  |     96 |
808 	 *        9  |    112 |
809 	 *       10  |    128 |
810 	 *   --------+--------+
811 	 *       11  |    192 |
812 	 *       12  |    256 |
813 	 *       13  |    320 |
814 	 *       14  |    384 |
815 	 *       15  |    448 |
816 	 *       16  |    512 |
817 	 *   --------+--------+
818 	 *       17  |    768 |
819 	 *       18  |   1024 |
820 	 *       19  |   1280 |
821 	 *           :        :
822 	 *       27  |   3328 |
823 	 *       28  |   3584 |
824 	 *       29  |   3840 |
825 	 *   --------+--------+
826 	 *       30  |  4 KiB |
827 	 *       31  |  6 KiB |
828 	 *       33  |  8 KiB |
829 	 *           :        :
830 	 *       43  | 28 KiB |
831 	 *       44  | 30 KiB |
832 	 *       45  | 32 KiB |
833 	 *   --------+--------+
834 	 */
835 	arena_bin_t		bins[1]; /* Dynamically sized. */
836 };
837 
838 /******************************************************************************/
839 /*
840  * Thread cache data structures.
841  */
842 
843 #ifdef MALLOC_TCACHE
844 typedef struct tcache_bin_s tcache_bin_t;
845 struct tcache_bin_s {
846 #  ifdef MALLOC_STATS
847 	tcache_bin_stats_t tstats;
848 #  endif
849 	unsigned	low_water;	/* Min # cached since last GC. */
850 	unsigned	high_water;	/* Max # cached since last GC. */
851 	unsigned	ncached;	/* # of cached objects. */
852 	void		*slots[1];	/* Dynamically sized. */
853 };
854 
855 struct tcache_s {
856 #  ifdef MALLOC_STATS
857 	ql_elm(tcache_t) link;		/* Used for aggregating stats. */
858 #  endif
859 	arena_t		*arena;		/* This thread's arena. */
860 	unsigned	ev_cnt;		/* Event count since incremental GC. */
861 	unsigned	next_gc_bin;	/* Next bin to GC. */
862 	tcache_bin_t	*tbins[1];	/* Dynamically sized. */
863 };
864 #endif
865 
866 /******************************************************************************/
867 /*
868  * Data.
869  */
870 
871 /* Number of CPUs. */
872 static unsigned		ncpus;
873 
874 /* Various bin-related settings. */
875 #ifdef MALLOC_TINY		/* Number of (2^n)-spaced tiny bins. */
876 #  define		ntbins	((unsigned)(LG_QUANTUM - LG_TINY_MIN))
877 #else
878 #  define		ntbins	0
879 #endif
880 static unsigned		nqbins; /* Number of quantum-spaced bins. */
881 static unsigned		ncbins; /* Number of cacheline-spaced bins. */
882 static unsigned		nsbins; /* Number of subpage-spaced bins. */
883 static unsigned		nmbins; /* Number of medium bins. */
884 static unsigned		nbins;
885 static unsigned		mbin0; /* mbin offset (nbins - nmbins). */
886 #ifdef MALLOC_TINY
887 #  define		tspace_max	((size_t)(QUANTUM >> 1))
888 #endif
889 #define			qspace_min	QUANTUM
890 static size_t		qspace_max;
891 static size_t		cspace_min;
892 static size_t		cspace_max;
893 static size_t		sspace_min;
894 static size_t		sspace_max;
895 #define			small_maxclass	sspace_max
896 #define			medium_min	PAGE_SIZE
897 static size_t		medium_max;
898 #define			bin_maxclass	medium_max
899 
900 /*
901  * Soft limit on the number of medium size classes.  Spacing between medium
902  * size classes never exceeds pagesize, which can force more than NBINS_MAX
903  * medium size classes.
904  */
905 #define	NMBINS_MAX	16
906 /* Spacing between medium size classes. */
907 static size_t		lg_mspace;
908 static size_t		mspace_mask;
909 
910 static uint8_t const	*small_size2bin;
911 /*
912  * const_small_size2bin is a static constant lookup table that in the common
913  * case can be used as-is for small_size2bin.  For dynamically linked programs,
914  * this avoids a page of memory overhead per process.
915  */
916 #define	S2B_1(i)	i,
917 #define	S2B_2(i)	S2B_1(i) S2B_1(i)
918 #define	S2B_4(i)	S2B_2(i) S2B_2(i)
919 #define	S2B_8(i)	S2B_4(i) S2B_4(i)
920 #define	S2B_16(i)	S2B_8(i) S2B_8(i)
921 #define	S2B_32(i)	S2B_16(i) S2B_16(i)
922 #define	S2B_64(i)	S2B_32(i) S2B_32(i)
923 #define	S2B_128(i)	S2B_64(i) S2B_64(i)
924 #define	S2B_256(i)	S2B_128(i) S2B_128(i)
925 static const uint8_t	const_small_size2bin[PAGE_SIZE - 255] = {
926 	S2B_1(0xffU)		/*    0 */
927 #if (LG_QUANTUM == 4)
928 /* 64-bit system ************************/
929 #  ifdef MALLOC_TINY
930 	S2B_2(0)		/*    2 */
931 	S2B_2(1)		/*    4 */
932 	S2B_4(2)		/*    8 */
933 	S2B_8(3)		/*   16 */
934 #    define S2B_QMIN 3
935 #  else
936 	S2B_16(0)		/*   16 */
937 #    define S2B_QMIN 0
938 #  endif
939 	S2B_16(S2B_QMIN + 1)	/*   32 */
940 	S2B_16(S2B_QMIN + 2)	/*   48 */
941 	S2B_16(S2B_QMIN + 3)	/*   64 */
942 	S2B_16(S2B_QMIN + 4)	/*   80 */
943 	S2B_16(S2B_QMIN + 5)	/*   96 */
944 	S2B_16(S2B_QMIN + 6)	/*  112 */
945 	S2B_16(S2B_QMIN + 7)	/*  128 */
946 #  define S2B_CMIN (S2B_QMIN + 8)
947 #else
948 /* 32-bit system ************************/
949 #  ifdef MALLOC_TINY
950 	S2B_2(0)		/*    2 */
951 	S2B_2(1)		/*    4 */
952 	S2B_4(2)		/*    8 */
953 #    define S2B_QMIN 2
954 #  else
955 	S2B_8(0)		/*    8 */
956 #    define S2B_QMIN 0
957 #  endif
958 	S2B_8(S2B_QMIN + 1)	/*   16 */
959 	S2B_8(S2B_QMIN + 2)	/*   24 */
960 	S2B_8(S2B_QMIN + 3)	/*   32 */
961 	S2B_8(S2B_QMIN + 4)	/*   40 */
962 	S2B_8(S2B_QMIN + 5)	/*   48 */
963 	S2B_8(S2B_QMIN + 6)	/*   56 */
964 	S2B_8(S2B_QMIN + 7)	/*   64 */
965 	S2B_8(S2B_QMIN + 8)	/*   72 */
966 	S2B_8(S2B_QMIN + 9)	/*   80 */
967 	S2B_8(S2B_QMIN + 10)	/*   88 */
968 	S2B_8(S2B_QMIN + 11)	/*   96 */
969 	S2B_8(S2B_QMIN + 12)	/*  104 */
970 	S2B_8(S2B_QMIN + 13)	/*  112 */
971 	S2B_8(S2B_QMIN + 14)	/*  120 */
972 	S2B_8(S2B_QMIN + 15)	/*  128 */
973 #  define S2B_CMIN (S2B_QMIN + 16)
974 #endif
975 /****************************************/
976 	S2B_64(S2B_CMIN + 0)	/*  192 */
977 	S2B_64(S2B_CMIN + 1)	/*  256 */
978 	S2B_64(S2B_CMIN + 2)	/*  320 */
979 	S2B_64(S2B_CMIN + 3)	/*  384 */
980 	S2B_64(S2B_CMIN + 4)	/*  448 */
981 	S2B_64(S2B_CMIN + 5)	/*  512 */
982 #  define S2B_SMIN (S2B_CMIN + 6)
983 	S2B_256(S2B_SMIN + 0)	/*  768 */
984 	S2B_256(S2B_SMIN + 1)	/* 1024 */
985 	S2B_256(S2B_SMIN + 2)	/* 1280 */
986 	S2B_256(S2B_SMIN + 3)	/* 1536 */
987 	S2B_256(S2B_SMIN + 4)	/* 1792 */
988 	S2B_256(S2B_SMIN + 5)	/* 2048 */
989 	S2B_256(S2B_SMIN + 6)	/* 2304 */
990 	S2B_256(S2B_SMIN + 7)	/* 2560 */
991 	S2B_256(S2B_SMIN + 8)	/* 2816 */
992 	S2B_256(S2B_SMIN + 9)	/* 3072 */
993 	S2B_256(S2B_SMIN + 10)	/* 3328 */
994 	S2B_256(S2B_SMIN + 11)	/* 3584 */
995 	S2B_256(S2B_SMIN + 12)	/* 3840 */
996 #if (PAGE_SHIFT == 13)
997 	S2B_256(S2B_SMIN + 13)	/* 4096 */
998 	S2B_256(S2B_SMIN + 14)	/* 4352 */
999 	S2B_256(S2B_SMIN + 15)	/* 4608 */
1000 	S2B_256(S2B_SMIN + 16)	/* 4864 */
1001 	S2B_256(S2B_SMIN + 17)	/* 5120 */
1002 	S2B_256(S2B_SMIN + 18)	/* 5376 */
1003 	S2B_256(S2B_SMIN + 19)	/* 5632 */
1004 	S2B_256(S2B_SMIN + 20)	/* 5888 */
1005 	S2B_256(S2B_SMIN + 21)	/* 6144 */
1006 	S2B_256(S2B_SMIN + 22)	/* 6400 */
1007 	S2B_256(S2B_SMIN + 23)	/* 6656 */
1008 	S2B_256(S2B_SMIN + 24)	/* 6912 */
1009 	S2B_256(S2B_SMIN + 25)	/* 7168 */
1010 	S2B_256(S2B_SMIN + 26)	/* 7424 */
1011 	S2B_256(S2B_SMIN + 27)	/* 7680 */
1012 	S2B_256(S2B_SMIN + 28)	/* 7936 */
1013 #endif
1014 };
1015 #undef S2B_1
1016 #undef S2B_2
1017 #undef S2B_4
1018 #undef S2B_8
1019 #undef S2B_16
1020 #undef S2B_32
1021 #undef S2B_64
1022 #undef S2B_128
1023 #undef S2B_256
1024 #undef S2B_QMIN
1025 #undef S2B_CMIN
1026 #undef S2B_SMIN
1027 
1028 /* Various chunk-related settings. */
1029 static size_t		chunksize;
1030 static size_t		chunksize_mask; /* (chunksize - 1). */
1031 static size_t		chunk_npages;
1032 static size_t		arena_chunk_header_npages;
1033 static size_t		arena_maxclass; /* Max size class for arenas. */
1034 
1035 /********/
1036 /*
1037  * Chunks.
1038  */
1039 
1040 /* Protects chunk-related data structures. */
1041 static malloc_mutex_t	huge_mtx;
1042 
1043 /* Tree of chunks that are stand-alone huge allocations. */
1044 static extent_tree_t	huge;
1045 
1046 #ifdef MALLOC_DSS
1047 /*
1048  * Protects sbrk() calls.  This avoids malloc races among threads, though it
1049  * does not protect against races with threads that call sbrk() directly.
1050  */
1051 static malloc_mutex_t	dss_mtx;
1052 /* Base address of the DSS. */
1053 static void		*dss_base;
1054 /* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */
1055 static void		*dss_prev;
1056 /* Current upper limit on DSS addresses. */
1057 static void		*dss_max;
1058 
1059 /*
1060  * Trees of chunks that were previously allocated (trees differ only in node
1061  * ordering).  These are used when allocating chunks, in an attempt to re-use
1062  * address space.  Depending on function, different tree orderings are needed,
1063  * which is why there are two trees with the same contents.
1064  */
1065 static extent_tree_t	dss_chunks_szad;
1066 static extent_tree_t	dss_chunks_ad;
1067 #endif
1068 
1069 #ifdef MALLOC_STATS
1070 /* Huge allocation statistics. */
1071 static uint64_t		huge_nmalloc;
1072 static uint64_t		huge_ndalloc;
1073 static size_t		huge_allocated;
1074 #endif
1075 
1076 /****************************/
1077 /*
1078  * base (internal allocation).
1079  */
1080 
1081 /*
1082  * Current pages that are being used for internal memory allocations.  These
1083  * pages are carved up in cacheline-size quanta, so that there is no chance of
1084  * false cache line sharing.
1085  */
1086 static void		*base_pages;
1087 static void		*base_next_addr;
1088 static void		*base_past_addr; /* Addr immediately past base_pages. */
1089 static extent_node_t	*base_nodes;
1090 static malloc_mutex_t	base_mtx;
1091 #ifdef MALLOC_STATS
1092 static size_t		base_mapped;
1093 #endif
1094 
1095 /********/
1096 /*
1097  * Arenas.
1098  */
1099 
1100 /*
1101  * Arenas that are used to service external requests.  Not all elements of the
1102  * arenas array are necessarily used; arenas are created lazily as needed.
1103  */
1104 static arena_t		**arenas;
1105 static unsigned		narenas;
1106 #ifndef NO_TLS
1107 static unsigned		next_arena;
1108 #endif
1109 static pthread_mutex_t	arenas_lock; /* Protects arenas initialization. */
1110 
1111 #ifndef NO_TLS
1112 /*
1113  * Map of _pthread_self() --> arenas[???], used for selecting an arena to use
1114  * for allocations.
1115  */
1116 static __thread arena_t		*arenas_map TLS_MODEL;
1117 #endif
1118 
1119 #ifdef MALLOC_TCACHE
1120 /* Map of thread-specific caches. */
1121 static __thread tcache_t	*tcache_tls TLS_MODEL;
1122 
1123 /*
1124  * Number of cache slots for each bin in the thread cache, or 0 if tcache is
1125  * disabled.
1126  */
1127 size_t				tcache_nslots;
1128 
1129 /* Number of tcache allocation/deallocation events between incremental GCs. */
1130 unsigned			tcache_gc_incr;
1131 #endif
1132 
1133 /*
1134  * Used by chunk_alloc_mmap() to decide whether to attempt the fast path and
1135  * potentially avoid some system calls.  We can get away without TLS here,
1136  * since the state of mmap_unaligned only affects performance, rather than
1137  * correct function.
1138  */
1139 #ifndef NO_TLS
1140 static __thread bool	mmap_unaligned TLS_MODEL;
1141 #else
1142 static		bool	mmap_unaligned;
1143 #endif
1144 
1145 #ifdef MALLOC_STATS
1146 static malloc_mutex_t	chunks_mtx;
1147 /* Chunk statistics. */
1148 static chunk_stats_t	stats_chunks;
1149 #endif
1150 
1151 /*******************************/
1152 /*
1153  * Runtime configuration options.
1154  */
1155 const char	*_malloc_options;
1156 
1157 #ifndef MALLOC_PRODUCTION
1158 static bool	opt_abort = true;
1159 static bool	opt_junk = true;
1160 #else
1161 static bool	opt_abort = false;
1162 static bool	opt_junk = false;
1163 #endif
1164 #ifdef MALLOC_TCACHE
1165 static size_t	opt_lg_tcache_nslots = LG_TCACHE_NSLOTS_DEFAULT;
1166 static ssize_t	opt_lg_tcache_gc_sweep = LG_TCACHE_GC_SWEEP_DEFAULT;
1167 #endif
1168 #ifdef MALLOC_DSS
1169 static bool	opt_dss = true;
1170 static bool	opt_mmap = true;
1171 #endif
1172 static ssize_t	opt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT;
1173 static bool	opt_stats_print = false;
1174 static size_t	opt_lg_qspace_max = LG_QSPACE_MAX_DEFAULT;
1175 static size_t	opt_lg_cspace_max = LG_CSPACE_MAX_DEFAULT;
1176 static size_t	opt_lg_medium_max = LG_MEDIUM_MAX_DEFAULT;
1177 static size_t	opt_lg_chunk = LG_CHUNK_DEFAULT;
1178 static bool	opt_utrace = false;
1179 static bool	opt_sysv = false;
1180 static bool	opt_xmalloc = false;
1181 static bool	opt_zero = false;
1182 static int	opt_narenas_lshift = 0;
1183 
1184 typedef struct {
1185 	void	*p;
1186 	size_t	s;
1187 	void	*r;
1188 } malloc_utrace_t;
1189 
1190 #define	UTRACE(a, b, c)							\
1191 	if (opt_utrace) {						\
1192 		malloc_utrace_t ut;					\
1193 		ut.p = (a);						\
1194 		ut.s = (b);						\
1195 		ut.r = (c);						\
1196 		utrace(&ut, sizeof(ut));				\
1197 	}
1198 
1199 /******************************************************************************/
1200 /*
1201  * Begin function prototypes for non-inline static functions.
1202  */
1203 
1204 static void	malloc_mutex_init(malloc_mutex_t *mutex);
1205 static bool	malloc_spin_init(pthread_mutex_t *lock);
1206 #ifdef MALLOC_TINY
1207 static size_t	pow2_ceil(size_t x);
1208 #endif
1209 static void	wrtmessage(const char *p1, const char *p2, const char *p3,
1210 		const char *p4);
1211 #ifdef MALLOC_STATS
1212 static void	malloc_printf(const char *format, ...);
1213 #endif
1214 static char	*umax2s(uintmax_t x, unsigned base, char *s);
1215 #ifdef MALLOC_DSS
1216 static bool	base_pages_alloc_dss(size_t minsize);
1217 #endif
1218 static bool	base_pages_alloc_mmap(size_t minsize);
1219 static bool	base_pages_alloc(size_t minsize);
1220 static void	*base_alloc(size_t size);
1221 static void	*base_calloc(size_t number, size_t size);
1222 static extent_node_t *base_node_alloc(void);
1223 static void	base_node_dealloc(extent_node_t *node);
1224 static void	*pages_map(void *addr, size_t size);
1225 static void	pages_unmap(void *addr, size_t size);
1226 #ifdef MALLOC_DSS
1227 static void	*chunk_alloc_dss(size_t size, bool *zero);
1228 static void	*chunk_recycle_dss(size_t size, bool *zero);
1229 #endif
1230 static void	*chunk_alloc_mmap_slow(size_t size, bool unaligned);
1231 static void	*chunk_alloc_mmap(size_t size);
1232 static void	*chunk_alloc(size_t size, bool *zero);
1233 #ifdef MALLOC_DSS
1234 static extent_node_t *chunk_dealloc_dss_record(void *chunk, size_t size);
1235 static bool	chunk_dealloc_dss(void *chunk, size_t size);
1236 #endif
1237 static void	chunk_dealloc_mmap(void *chunk, size_t size);
1238 static void	chunk_dealloc(void *chunk, size_t size);
1239 #ifndef NO_TLS
1240 static arena_t	*choose_arena_hard(void);
1241 #endif
1242 static void	arena_run_split(arena_t *arena, arena_run_t *run, size_t size,
1243     bool large, bool zero);
1244 static arena_chunk_t *arena_chunk_alloc(arena_t *arena);
1245 static void	arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk);
1246 static arena_run_t *arena_run_alloc(arena_t *arena, size_t size, bool large,
1247     bool zero);
1248 static void	arena_purge(arena_t *arena);
1249 static void	arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty);
1250 static void	arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk,
1251     arena_run_t *run, size_t oldsize, size_t newsize);
1252 static void	arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk,
1253     arena_run_t *run, size_t oldsize, size_t newsize, bool dirty);
1254 static arena_run_t *arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin);
1255 static void	*arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin);
1256 static size_t	arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size);
1257 #ifdef MALLOC_TCACHE
1258 static void	tcache_bin_fill(tcache_t *tcache, tcache_bin_t *tbin,
1259     size_t binind);
1260 static void	*tcache_alloc_hard(tcache_t *tcache, tcache_bin_t *tbin,
1261     size_t binind);
1262 #endif
1263 static void	*arena_malloc_medium(arena_t *arena, size_t size, bool zero);
1264 static void	*arena_malloc_large(arena_t *arena, size_t size, bool zero);
1265 static void	*arena_palloc(arena_t *arena, size_t alignment, size_t size,
1266     size_t alloc_size);
1267 static bool	arena_is_large(const void *ptr);
1268 static size_t	arena_salloc(const void *ptr);
1269 static void
1270 arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
1271     arena_bin_t *bin);
1272 #ifdef MALLOC_STATS
1273 static void	arena_stats_print(arena_t *arena);
1274 #endif
1275 static void	stats_print_atexit(void);
1276 #ifdef MALLOC_TCACHE
1277 static void	tcache_bin_flush(tcache_bin_t *tbin, size_t binind,
1278     unsigned rem);
1279 #endif
1280 static void	arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk,
1281     void *ptr);
1282 #ifdef MALLOC_TCACHE
1283 static void	arena_dalloc_hard(arena_t *arena, arena_chunk_t *chunk,
1284     void *ptr, arena_chunk_map_t *mapelm, tcache_t *tcache);
1285 #endif
1286 static void	arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
1287     void *ptr, size_t size, size_t oldsize);
1288 static bool	arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
1289     void *ptr, size_t size, size_t oldsize);
1290 static bool	arena_ralloc_large(void *ptr, size_t size, size_t oldsize);
1291 static void	*arena_ralloc(void *ptr, size_t size, size_t oldsize);
1292 static bool	arena_new(arena_t *arena, unsigned ind);
1293 static arena_t	*arenas_extend(unsigned ind);
1294 #ifdef MALLOC_TCACHE
1295 static tcache_bin_t	*tcache_bin_create(arena_t *arena);
1296 static void	tcache_bin_destroy(tcache_t *tcache, tcache_bin_t *tbin,
1297     unsigned binind);
1298 #  ifdef MALLOC_STATS
1299 static void	tcache_stats_merge(tcache_t *tcache, arena_t *arena);
1300 #  endif
1301 static tcache_t	*tcache_create(arena_t *arena);
1302 static void	tcache_destroy(tcache_t *tcache);
1303 #endif
1304 static void	*huge_malloc(size_t size, bool zero);
1305 static void	*huge_palloc(size_t alignment, size_t size);
1306 static void	*huge_ralloc(void *ptr, size_t size, size_t oldsize);
1307 static void	huge_dalloc(void *ptr);
1308 static void	malloc_stats_print(void);
1309 #ifdef MALLOC_DEBUG
1310 static void	small_size2bin_validate(void);
1311 #endif
1312 static bool	small_size2bin_init(void);
1313 static bool	small_size2bin_init_hard(void);
1314 static unsigned	malloc_ncpus(void);
1315 static bool	malloc_init_hard(void);
1316 
1317 /*
1318  * End function prototypes.
1319  */
1320 /******************************************************************************/
1321 
1322 static void
wrtmessage(const char * p1,const char * p2,const char * p3,const char * p4)1323 wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
1324 {
1325 
1326 	if (_write(STDERR_FILENO, p1, strlen(p1)) < 0
1327 	    || _write(STDERR_FILENO, p2, strlen(p2)) < 0
1328 	    || _write(STDERR_FILENO, p3, strlen(p3)) < 0
1329 	    || _write(STDERR_FILENO, p4, strlen(p4)) < 0)
1330 		return;
1331 }
1332 
1333 void	(*_malloc_message)(const char *p1, const char *p2, const char *p3,
1334 	    const char *p4) = wrtmessage;
1335 
1336 /*
1337  * We don't want to depend on vsnprintf() for production builds, since that can
1338  * cause unnecessary bloat for static binaries.  umax2s() provides minimal
1339  * integer printing functionality, so that malloc_printf() use can be limited to
1340  * MALLOC_STATS code.
1341  */
1342 #define	UMAX2S_BUFSIZE	65
1343 static char *
umax2s(uintmax_t x,unsigned base,char * s)1344 umax2s(uintmax_t x, unsigned base, char *s)
1345 {
1346 	unsigned i;
1347 
1348 	i = UMAX2S_BUFSIZE - 1;
1349 	s[i] = '\0';
1350 	switch (base) {
1351 	case 10:
1352 		do {
1353 			i--;
1354 			s[i] = "0123456789"[x % 10];
1355 			x /= 10;
1356 		} while (x > 0);
1357 		break;
1358 	case 16:
1359 		do {
1360 			i--;
1361 			s[i] = "0123456789abcdef"[x & 0xf];
1362 			x >>= 4;
1363 		} while (x > 0);
1364 		break;
1365 	default:
1366 		do {
1367 			i--;
1368 			s[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % base];
1369 			x /= base;
1370 		} while (x > 0);
1371 	}
1372 
1373 	return (&s[i]);
1374 }
1375 
1376 /*
1377  * Define a custom assert() in order to reduce the chances of deadlock during
1378  * assertion failure.
1379  */
1380 #ifdef MALLOC_DEBUG
1381 #  define assert(e) do {						\
1382 	if (!(e)) {							\
1383 		char line_buf[UMAX2S_BUFSIZE];				\
1384 		_malloc_message(_getprogname(), ": (malloc) ",		\
1385 		    __FILE__, ":");					\
1386 		_malloc_message(umax2s(__LINE__, 10, line_buf),		\
1387 		    ": Failed assertion: ", "\"", #e);			\
1388 		_malloc_message("\"\n", "", "", "");			\
1389 		abort();						\
1390 	}								\
1391 } while (0)
1392 #else
1393 #define assert(e)
1394 #endif
1395 
1396 #ifdef MALLOC_STATS
1397 /*
1398  * Print to stderr in such a way as to (hopefully) avoid memory allocation.
1399  */
1400 static void
malloc_printf(const char * format,...)1401 malloc_printf(const char *format, ...)
1402 {
1403 	char buf[4096];
1404 	va_list ap;
1405 
1406 	va_start(ap, format);
1407 	vsnprintf(buf, sizeof(buf), format, ap);
1408 	va_end(ap);
1409 	_malloc_message(buf, "", "", "");
1410 }
1411 #endif
1412 
1413 /******************************************************************************/
1414 /*
1415  * Begin mutex.  We can't use normal pthread mutexes in all places, because
1416  * they require malloc()ed memory, which causes bootstrapping issues in some
1417  * cases.
1418  */
1419 
1420 static void
malloc_mutex_init(malloc_mutex_t * mutex)1421 malloc_mutex_init(malloc_mutex_t *mutex)
1422 {
1423 	static const spinlock_t lock = _SPINLOCK_INITIALIZER;
1424 
1425 	mutex->lock = lock;
1426 }
1427 
1428 static inline void
malloc_mutex_lock(malloc_mutex_t * mutex)1429 malloc_mutex_lock(malloc_mutex_t *mutex)
1430 {
1431 
1432 	if (__isthreaded)
1433 		_SPINLOCK(&mutex->lock);
1434 }
1435 
1436 static inline void
malloc_mutex_unlock(malloc_mutex_t * mutex)1437 malloc_mutex_unlock(malloc_mutex_t *mutex)
1438 {
1439 
1440 	if (__isthreaded)
1441 		_SPINUNLOCK(&mutex->lock);
1442 }
1443 
1444 /*
1445  * End mutex.
1446  */
1447 /******************************************************************************/
1448 /*
1449  * Begin spin lock.  Spin locks here are actually adaptive mutexes that block
1450  * after a period of spinning, because unbounded spinning would allow for
1451  * priority inversion.
1452  */
1453 
1454 /*
1455  * We use an unpublished interface to initialize pthread mutexes with an
1456  * allocation callback, in order to avoid infinite recursion.
1457  */
1458 int	_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
1459     void *(calloc_cb)(size_t, size_t));
1460 
1461 __weak_reference(_pthread_mutex_init_calloc_cb_stub,
1462     _pthread_mutex_init_calloc_cb);
1463 
1464 int
_pthread_mutex_init_calloc_cb_stub(pthread_mutex_t * mutex,void * (calloc_cb)(size_t,size_t))1465 _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex,
1466     void *(calloc_cb)(size_t, size_t))
1467 {
1468 
1469 	return (0);
1470 }
1471 
1472 static bool
malloc_spin_init(pthread_mutex_t * lock)1473 malloc_spin_init(pthread_mutex_t *lock)
1474 {
1475 
1476 	if (_pthread_mutex_init_calloc_cb(lock, base_calloc) != 0)
1477 		return (true);
1478 
1479 	return (false);
1480 }
1481 
1482 static inline void
malloc_spin_lock(pthread_mutex_t * lock)1483 malloc_spin_lock(pthread_mutex_t *lock)
1484 {
1485 
1486 	if (__isthreaded) {
1487 		if (_pthread_mutex_trylock(lock) != 0) {
1488 			/* Exponentially back off if there are multiple CPUs. */
1489 			if (ncpus > 1) {
1490 				unsigned i;
1491 				volatile unsigned j;
1492 
1493 				for (i = 1; i <= LG_SPIN_LIMIT; i++) {
1494 					for (j = 0; j < (1U << i); j++) {
1495 						CPU_SPINWAIT;
1496 					}
1497 
1498 					if (_pthread_mutex_trylock(lock) == 0)
1499 						return;
1500 				}
1501 			}
1502 
1503 			/*
1504 			 * Spinning failed.  Block until the lock becomes
1505 			 * available, in order to avoid indefinite priority
1506 			 * inversion.
1507 			 */
1508 			_pthread_mutex_lock(lock);
1509 		}
1510 	}
1511 }
1512 
1513 static inline void
malloc_spin_unlock(pthread_mutex_t * lock)1514 malloc_spin_unlock(pthread_mutex_t *lock)
1515 {
1516 
1517 	if (__isthreaded)
1518 		_pthread_mutex_unlock(lock);
1519 }
1520 
1521 /*
1522  * End spin lock.
1523  */
1524 /******************************************************************************/
1525 /*
1526  * Begin Utility functions/macros.
1527  */
1528 
1529 /* Return the chunk address for allocation address a. */
1530 #define	CHUNK_ADDR2BASE(a)						\
1531 	((void *)((uintptr_t)(a) & ~chunksize_mask))
1532 
1533 /* Return the chunk offset of address a. */
1534 #define	CHUNK_ADDR2OFFSET(a)						\
1535 	((size_t)((uintptr_t)(a) & chunksize_mask))
1536 
1537 /* Return the smallest chunk multiple that is >= s. */
1538 #define	CHUNK_CEILING(s)						\
1539 	(((s) + chunksize_mask) & ~chunksize_mask)
1540 
1541 /* Return the smallest quantum multiple that is >= a. */
1542 #define	QUANTUM_CEILING(a)						\
1543 	(((a) + QUANTUM_MASK) & ~QUANTUM_MASK)
1544 
1545 /* Return the smallest cacheline multiple that is >= s. */
1546 #define	CACHELINE_CEILING(s)						\
1547 	(((s) + CACHELINE_MASK) & ~CACHELINE_MASK)
1548 
1549 /* Return the smallest subpage multiple that is >= s. */
1550 #define	SUBPAGE_CEILING(s)						\
1551 	(((s) + SUBPAGE_MASK) & ~SUBPAGE_MASK)
1552 
1553 /* Return the smallest medium size class that is >= s. */
1554 #define	MEDIUM_CEILING(s)						\
1555 	(((s) + mspace_mask) & ~mspace_mask)
1556 
1557 /* Return the smallest pagesize multiple that is >= s. */
1558 #define	PAGE_CEILING(s)							\
1559 	(((s) + PAGE_MASK) & ~PAGE_MASK)
1560 
1561 #ifdef MALLOC_TINY
1562 /* Compute the smallest power of 2 that is >= x. */
1563 static size_t
pow2_ceil(size_t x)1564 pow2_ceil(size_t x)
1565 {
1566 
1567 	x--;
1568 	x |= x >> 1;
1569 	x |= x >> 2;
1570 	x |= x >> 4;
1571 	x |= x >> 8;
1572 	x |= x >> 16;
1573 #if (SIZEOF_PTR == 8)
1574 	x |= x >> 32;
1575 #endif
1576 	x++;
1577 	return (x);
1578 }
1579 #endif
1580 
1581 /******************************************************************************/
1582 
1583 #ifdef MALLOC_DSS
1584 static bool
base_pages_alloc_dss(size_t minsize)1585 base_pages_alloc_dss(size_t minsize)
1586 {
1587 
1588 	/*
1589 	 * Do special DSS allocation here, since base allocations don't need to
1590 	 * be chunk-aligned.
1591 	 */
1592 	malloc_mutex_lock(&dss_mtx);
1593 	if (dss_prev != (void *)-1) {
1594 		intptr_t incr;
1595 		size_t csize = CHUNK_CEILING(minsize);
1596 
1597 		do {
1598 			/* Get the current end of the DSS. */
1599 			dss_max = sbrk(0);
1600 
1601 			/*
1602 			 * Calculate how much padding is necessary to
1603 			 * chunk-align the end of the DSS.  Don't worry about
1604 			 * dss_max not being chunk-aligned though.
1605 			 */
1606 			incr = (intptr_t)chunksize
1607 			    - (intptr_t)CHUNK_ADDR2OFFSET(dss_max);
1608 			assert(incr >= 0);
1609 			if ((size_t)incr < minsize)
1610 				incr += csize;
1611 
1612 			dss_prev = sbrk(incr);
1613 			if (dss_prev == dss_max) {
1614 				/* Success. */
1615 				dss_max = (void *)((intptr_t)dss_prev + incr);
1616 				base_pages = dss_prev;
1617 				base_next_addr = base_pages;
1618 				base_past_addr = dss_max;
1619 #ifdef MALLOC_STATS
1620 				base_mapped += incr;
1621 #endif
1622 				malloc_mutex_unlock(&dss_mtx);
1623 				return (false);
1624 			}
1625 		} while (dss_prev != (void *)-1);
1626 	}
1627 	malloc_mutex_unlock(&dss_mtx);
1628 
1629 	return (true);
1630 }
1631 #endif
1632 
1633 static bool
base_pages_alloc_mmap(size_t minsize)1634 base_pages_alloc_mmap(size_t minsize)
1635 {
1636 	size_t csize;
1637 
1638 	assert(minsize != 0);
1639 	csize = PAGE_CEILING(minsize);
1640 	base_pages = pages_map(NULL, csize);
1641 	if (base_pages == NULL)
1642 		return (true);
1643 	base_next_addr = base_pages;
1644 	base_past_addr = (void *)((uintptr_t)base_pages + csize);
1645 #ifdef MALLOC_STATS
1646 	base_mapped += csize;
1647 #endif
1648 
1649 	return (false);
1650 }
1651 
1652 static bool
base_pages_alloc(size_t minsize)1653 base_pages_alloc(size_t minsize)
1654 {
1655 
1656 #ifdef MALLOC_DSS
1657 	if (opt_mmap && minsize != 0)
1658 #endif
1659 	{
1660 		if (base_pages_alloc_mmap(minsize) == false)
1661 			return (false);
1662 	}
1663 
1664 #ifdef MALLOC_DSS
1665 	if (opt_dss) {
1666 		if (base_pages_alloc_dss(minsize) == false)
1667 			return (false);
1668 	}
1669 
1670 #endif
1671 
1672 	return (true);
1673 }
1674 
1675 static void *
base_alloc(size_t size)1676 base_alloc(size_t size)
1677 {
1678 	void *ret;
1679 	size_t csize;
1680 
1681 	/* Round size up to nearest multiple of the cacheline size. */
1682 	csize = CACHELINE_CEILING(size);
1683 
1684 	malloc_mutex_lock(&base_mtx);
1685 	/* Make sure there's enough space for the allocation. */
1686 	if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) {
1687 		if (base_pages_alloc(csize)) {
1688 			malloc_mutex_unlock(&base_mtx);
1689 			return (NULL);
1690 		}
1691 	}
1692 	/* Allocate. */
1693 	ret = base_next_addr;
1694 	base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
1695 	malloc_mutex_unlock(&base_mtx);
1696 
1697 	return (ret);
1698 }
1699 
1700 static void *
base_calloc(size_t number,size_t size)1701 base_calloc(size_t number, size_t size)
1702 {
1703 	void *ret;
1704 
1705 	ret = base_alloc(number * size);
1706 	if (ret != NULL)
1707 		memset(ret, 0, number * size);
1708 
1709 	return (ret);
1710 }
1711 
1712 static extent_node_t *
base_node_alloc(void)1713 base_node_alloc(void)
1714 {
1715 	extent_node_t *ret;
1716 
1717 	malloc_mutex_lock(&base_mtx);
1718 	if (base_nodes != NULL) {
1719 		ret = base_nodes;
1720 		base_nodes = *(extent_node_t **)ret;
1721 		malloc_mutex_unlock(&base_mtx);
1722 	} else {
1723 		malloc_mutex_unlock(&base_mtx);
1724 		ret = (extent_node_t *)base_alloc(sizeof(extent_node_t));
1725 	}
1726 
1727 	return (ret);
1728 }
1729 
1730 static void
base_node_dealloc(extent_node_t * node)1731 base_node_dealloc(extent_node_t *node)
1732 {
1733 
1734 	malloc_mutex_lock(&base_mtx);
1735 	*(extent_node_t **)node = base_nodes;
1736 	base_nodes = node;
1737 	malloc_mutex_unlock(&base_mtx);
1738 }
1739 
1740 /*
1741  * End Utility functions/macros.
1742  */
1743 /******************************************************************************/
1744 /*
1745  * Begin extent tree code.
1746  */
1747 
1748 #ifdef MALLOC_DSS
1749 static inline int
extent_szad_comp(extent_node_t * a,extent_node_t * b)1750 extent_szad_comp(extent_node_t *a, extent_node_t *b)
1751 {
1752 	int ret;
1753 	size_t a_size = a->size;
1754 	size_t b_size = b->size;
1755 
1756 	ret = (a_size > b_size) - (a_size < b_size);
1757 	if (ret == 0) {
1758 		uintptr_t a_addr = (uintptr_t)a->addr;
1759 		uintptr_t b_addr = (uintptr_t)b->addr;
1760 
1761 		ret = (a_addr > b_addr) - (a_addr < b_addr);
1762 	}
1763 
1764 	return (ret);
1765 }
1766 
1767 /* Wrap red-black tree macros in functions. */
rb_gen(__unused static,extent_tree_szad_,extent_tree_t,extent_node_t,link_szad,extent_szad_comp)1768 rb_gen(__unused static, extent_tree_szad_, extent_tree_t, extent_node_t,
1769     link_szad, extent_szad_comp)
1770 #endif
1771 
1772 static inline int
1773 extent_ad_comp(extent_node_t *a, extent_node_t *b)
1774 {
1775 	uintptr_t a_addr = (uintptr_t)a->addr;
1776 	uintptr_t b_addr = (uintptr_t)b->addr;
1777 
1778 	return ((a_addr > b_addr) - (a_addr < b_addr));
1779 }
1780 
1781 /* Wrap red-black tree macros in functions. */
rb_gen(__unused static,extent_tree_ad_,extent_tree_t,extent_node_t,link_ad,extent_ad_comp)1782 rb_gen(__unused static, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad,
1783     extent_ad_comp)
1784 
1785 /*
1786  * End extent tree code.
1787  */
1788 /******************************************************************************/
1789 /*
1790  * Begin chunk management functions.
1791  */
1792 
1793 static void *
1794 pages_map(void *addr, size_t size)
1795 {
1796 	void *ret;
1797 
1798 	/*
1799 	 * We don't use MAP_FIXED here, because it can cause the *replacement*
1800 	 * of existing mappings, and we only want to create new mappings.
1801 	 */
1802 	ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
1803 	    -1, 0);
1804 	assert(ret != NULL);
1805 
1806 	if (ret == MAP_FAILED)
1807 		ret = NULL;
1808 	else if (addr != NULL && ret != addr) {
1809 		/*
1810 		 * We succeeded in mapping memory, but not in the right place.
1811 		 */
1812 		if (munmap(ret, size) == -1) {
1813 			char buf[STRERROR_BUF];
1814 
1815 			strerror_r(errno, buf, sizeof(buf));
1816 			_malloc_message(_getprogname(),
1817 			    ": (malloc) Error in munmap(): ", buf, "\n");
1818 			if (opt_abort)
1819 				abort();
1820 		}
1821 		ret = NULL;
1822 	}
1823 
1824 	assert(ret == NULL || (addr == NULL && ret != addr)
1825 	    || (addr != NULL && ret == addr));
1826 	return (ret);
1827 }
1828 
1829 static void
pages_unmap(void * addr,size_t size)1830 pages_unmap(void *addr, size_t size)
1831 {
1832 
1833 	if (munmap(addr, size) == -1) {
1834 		char buf[STRERROR_BUF];
1835 
1836 		strerror_r(errno, buf, sizeof(buf));
1837 		_malloc_message(_getprogname(),
1838 		    ": (malloc) Error in munmap(): ", buf, "\n");
1839 		if (opt_abort)
1840 			abort();
1841 	}
1842 }
1843 
1844 #ifdef MALLOC_DSS
1845 static void *
chunk_alloc_dss(size_t size,bool * zero)1846 chunk_alloc_dss(size_t size, bool *zero)
1847 {
1848 	void *ret;
1849 
1850 	ret = chunk_recycle_dss(size, zero);
1851 	if (ret != NULL)
1852 		return (ret);
1853 
1854 	/*
1855 	 * sbrk() uses a signed increment argument, so take care not to
1856 	 * interpret a huge allocation request as a negative increment.
1857 	 */
1858 	if ((intptr_t)size < 0)
1859 		return (NULL);
1860 
1861 	malloc_mutex_lock(&dss_mtx);
1862 	if (dss_prev != (void *)-1) {
1863 		intptr_t incr;
1864 
1865 		/*
1866 		 * The loop is necessary to recover from races with other
1867 		 * threads that are using the DSS for something other than
1868 		 * malloc.
1869 		 */
1870 		do {
1871 			/* Get the current end of the DSS. */
1872 			dss_max = sbrk(0);
1873 
1874 			/*
1875 			 * Calculate how much padding is necessary to
1876 			 * chunk-align the end of the DSS.
1877 			 */
1878 			incr = (intptr_t)size
1879 			    - (intptr_t)CHUNK_ADDR2OFFSET(dss_max);
1880 			if (incr == (intptr_t)size)
1881 				ret = dss_max;
1882 			else {
1883 				ret = (void *)((intptr_t)dss_max + incr);
1884 				incr += size;
1885 			}
1886 
1887 			dss_prev = sbrk(incr);
1888 			if (dss_prev == dss_max) {
1889 				/* Success. */
1890 				dss_max = (void *)((intptr_t)dss_prev + incr);
1891 				malloc_mutex_unlock(&dss_mtx);
1892 				*zero = true;
1893 				return (ret);
1894 			}
1895 		} while (dss_prev != (void *)-1);
1896 	}
1897 	malloc_mutex_unlock(&dss_mtx);
1898 
1899 	return (NULL);
1900 }
1901 
1902 static void *
chunk_recycle_dss(size_t size,bool * zero)1903 chunk_recycle_dss(size_t size, bool *zero)
1904 {
1905 	extent_node_t *node, key;
1906 
1907 	key.addr = NULL;
1908 	key.size = size;
1909 	malloc_mutex_lock(&dss_mtx);
1910 	node = extent_tree_szad_nsearch(&dss_chunks_szad, &key);
1911 	if (node != NULL) {
1912 		void *ret = node->addr;
1913 
1914 		/* Remove node from the tree. */
1915 		extent_tree_szad_remove(&dss_chunks_szad, node);
1916 		if (node->size == size) {
1917 			extent_tree_ad_remove(&dss_chunks_ad, node);
1918 			base_node_dealloc(node);
1919 		} else {
1920 			/*
1921 			 * Insert the remainder of node's address range as a
1922 			 * smaller chunk.  Its position within dss_chunks_ad
1923 			 * does not change.
1924 			 */
1925 			assert(node->size > size);
1926 			node->addr = (void *)((uintptr_t)node->addr + size);
1927 			node->size -= size;
1928 			extent_tree_szad_insert(&dss_chunks_szad, node);
1929 		}
1930 		malloc_mutex_unlock(&dss_mtx);
1931 
1932 		if (*zero)
1933 			memset(ret, 0, size);
1934 		return (ret);
1935 	}
1936 	malloc_mutex_unlock(&dss_mtx);
1937 
1938 	return (NULL);
1939 }
1940 #endif
1941 
1942 static void *
chunk_alloc_mmap_slow(size_t size,bool unaligned)1943 chunk_alloc_mmap_slow(size_t size, bool unaligned)
1944 {
1945 	void *ret;
1946 	size_t offset;
1947 
1948 	/* Beware size_t wrap-around. */
1949 	if (size + chunksize <= size)
1950 		return (NULL);
1951 
1952 	ret = pages_map(NULL, size + chunksize);
1953 	if (ret == NULL)
1954 		return (NULL);
1955 
1956 	/* Clean up unneeded leading/trailing space. */
1957 	offset = CHUNK_ADDR2OFFSET(ret);
1958 	if (offset != 0) {
1959 		/* Note that mmap() returned an unaligned mapping. */
1960 		unaligned = true;
1961 
1962 		/* Leading space. */
1963 		pages_unmap(ret, chunksize - offset);
1964 
1965 		ret = (void *)((uintptr_t)ret +
1966 		    (chunksize - offset));
1967 
1968 		/* Trailing space. */
1969 		pages_unmap((void *)((uintptr_t)ret + size),
1970 		    offset);
1971 	} else {
1972 		/* Trailing space only. */
1973 		pages_unmap((void *)((uintptr_t)ret + size),
1974 		    chunksize);
1975 	}
1976 
1977 	/*
1978 	 * If mmap() returned an aligned mapping, reset mmap_unaligned so that
1979 	 * the next chunk_alloc_mmap() execution tries the fast allocation
1980 	 * method.
1981 	 */
1982 	if (unaligned == false)
1983 		mmap_unaligned = false;
1984 
1985 	return (ret);
1986 }
1987 
1988 static void *
chunk_alloc_mmap(size_t size)1989 chunk_alloc_mmap(size_t size)
1990 {
1991 	void *ret;
1992 
1993 	/*
1994 	 * Ideally, there would be a way to specify alignment to mmap() (like
1995 	 * NetBSD has), but in the absence of such a feature, we have to work
1996 	 * hard to efficiently create aligned mappings.  The reliable, but
1997 	 * slow method is to create a mapping that is over-sized, then trim the
1998 	 * excess.  However, that always results in at least one call to
1999 	 * pages_unmap().
2000 	 *
2001 	 * A more optimistic approach is to try mapping precisely the right
2002 	 * amount, then try to append another mapping if alignment is off.  In
2003 	 * practice, this works out well as long as the application is not
2004 	 * interleaving mappings via direct mmap() calls.  If we do run into a
2005 	 * situation where there is an interleaved mapping and we are unable to
2006 	 * extend an unaligned mapping, our best option is to switch to the
2007 	 * slow method until mmap() returns another aligned mapping.  This will
2008 	 * tend to leave a gap in the memory map that is too small to cause
2009 	 * later problems for the optimistic method.
2010 	 *
2011 	 * Another possible confounding factor is address space layout
2012 	 * randomization (ASLR), which causes mmap(2) to disregard the
2013 	 * requested address.  mmap_unaligned tracks whether the previous
2014 	 * chunk_alloc_mmap() execution received any unaligned or relocated
2015 	 * mappings, and if so, the current execution will immediately fall
2016 	 * back to the slow method.  However, we keep track of whether the fast
2017 	 * method would have succeeded, and if so, we make a note to try the
2018 	 * fast method next time.
2019 	 */
2020 
2021 	if (mmap_unaligned == false) {
2022 		size_t offset;
2023 
2024 		ret = pages_map(NULL, size);
2025 		if (ret == NULL)
2026 			return (NULL);
2027 
2028 		offset = CHUNK_ADDR2OFFSET(ret);
2029 		if (offset != 0) {
2030 			mmap_unaligned = true;
2031 			/* Try to extend chunk boundary. */
2032 			if (pages_map((void *)((uintptr_t)ret + size),
2033 			    chunksize - offset) == NULL) {
2034 				/*
2035 				 * Extension failed.  Clean up, then revert to
2036 				 * the reliable-but-expensive method.
2037 				 */
2038 				pages_unmap(ret, size);
2039 				ret = chunk_alloc_mmap_slow(size, true);
2040 			} else {
2041 				/* Clean up unneeded leading space. */
2042 				pages_unmap(ret, chunksize - offset);
2043 				ret = (void *)((uintptr_t)ret + (chunksize -
2044 				    offset));
2045 			}
2046 		}
2047 	} else
2048 		ret = chunk_alloc_mmap_slow(size, false);
2049 
2050 	return (ret);
2051 }
2052 
2053 /*
2054  * If the caller specifies (*zero == false), it is still possible to receive
2055  * zeroed memory, in which case *zero is toggled to true.  arena_chunk_alloc()
2056  * takes advantage of this to avoid demanding zeroed chunks, but taking
2057  * advantage of them if they are returned.
2058  */
2059 static void *
chunk_alloc(size_t size,bool * zero)2060 chunk_alloc(size_t size, bool *zero)
2061 {
2062 	void *ret;
2063 
2064 	assert(size != 0);
2065 	assert((size & chunksize_mask) == 0);
2066 
2067 #ifdef MALLOC_DSS
2068 	if (opt_mmap)
2069 #endif
2070 	{
2071 		ret = chunk_alloc_mmap(size);
2072 		if (ret != NULL) {
2073 			*zero = true;
2074 			goto RETURN;
2075 		}
2076 	}
2077 
2078 #ifdef MALLOC_DSS
2079 	if (opt_dss) {
2080 		ret = chunk_alloc_dss(size, zero);
2081 		if (ret != NULL)
2082 			goto RETURN;
2083 	}
2084 #endif
2085 
2086 	/* All strategies for allocation failed. */
2087 	ret = NULL;
2088 RETURN:
2089 #ifdef MALLOC_STATS
2090 	if (ret != NULL) {
2091 		malloc_mutex_lock(&chunks_mtx);
2092 		stats_chunks.nchunks += (size / chunksize);
2093 		stats_chunks.curchunks += (size / chunksize);
2094 		if (stats_chunks.curchunks > stats_chunks.highchunks)
2095 			stats_chunks.highchunks = stats_chunks.curchunks;
2096 		malloc_mutex_unlock(&chunks_mtx);
2097 	}
2098 #endif
2099 
2100 	assert(CHUNK_ADDR2BASE(ret) == ret);
2101 	return (ret);
2102 }
2103 
2104 #ifdef MALLOC_DSS
2105 static extent_node_t *
chunk_dealloc_dss_record(void * chunk,size_t size)2106 chunk_dealloc_dss_record(void *chunk, size_t size)
2107 {
2108 	extent_node_t *node, *prev, key;
2109 
2110 	key.addr = (void *)((uintptr_t)chunk + size);
2111 	node = extent_tree_ad_nsearch(&dss_chunks_ad, &key);
2112 	/* Try to coalesce forward. */
2113 	if (node != NULL && node->addr == key.addr) {
2114 		/*
2115 		 * Coalesce chunk with the following address range.  This does
2116 		 * not change the position within dss_chunks_ad, so only
2117 		 * remove/insert from/into dss_chunks_szad.
2118 		 */
2119 		extent_tree_szad_remove(&dss_chunks_szad, node);
2120 		node->addr = chunk;
2121 		node->size += size;
2122 		extent_tree_szad_insert(&dss_chunks_szad, node);
2123 	} else {
2124 		/*
2125 		 * Coalescing forward failed, so insert a new node.  Drop
2126 		 * dss_mtx during node allocation, since it is possible that a
2127 		 * new base chunk will be allocated.
2128 		 */
2129 		malloc_mutex_unlock(&dss_mtx);
2130 		node = base_node_alloc();
2131 		malloc_mutex_lock(&dss_mtx);
2132 		if (node == NULL)
2133 			return (NULL);
2134 		node->addr = chunk;
2135 		node->size = size;
2136 		extent_tree_ad_insert(&dss_chunks_ad, node);
2137 		extent_tree_szad_insert(&dss_chunks_szad, node);
2138 	}
2139 
2140 	/* Try to coalesce backward. */
2141 	prev = extent_tree_ad_prev(&dss_chunks_ad, node);
2142 	if (prev != NULL && (void *)((uintptr_t)prev->addr + prev->size) ==
2143 	    chunk) {
2144 		/*
2145 		 * Coalesce chunk with the previous address range.  This does
2146 		 * not change the position within dss_chunks_ad, so only
2147 		 * remove/insert node from/into dss_chunks_szad.
2148 		 */
2149 		extent_tree_szad_remove(&dss_chunks_szad, prev);
2150 		extent_tree_ad_remove(&dss_chunks_ad, prev);
2151 
2152 		extent_tree_szad_remove(&dss_chunks_szad, node);
2153 		node->addr = prev->addr;
2154 		node->size += prev->size;
2155 		extent_tree_szad_insert(&dss_chunks_szad, node);
2156 
2157 		base_node_dealloc(prev);
2158 	}
2159 
2160 	return (node);
2161 }
2162 
2163 static bool
chunk_dealloc_dss(void * chunk,size_t size)2164 chunk_dealloc_dss(void *chunk, size_t size)
2165 {
2166 	bool ret;
2167 
2168 	malloc_mutex_lock(&dss_mtx);
2169 	if ((uintptr_t)chunk >= (uintptr_t)dss_base
2170 	    && (uintptr_t)chunk < (uintptr_t)dss_max) {
2171 		extent_node_t *node;
2172 
2173 		/* Try to coalesce with other unused chunks. */
2174 		node = chunk_dealloc_dss_record(chunk, size);
2175 		if (node != NULL) {
2176 			chunk = node->addr;
2177 			size = node->size;
2178 		}
2179 
2180 		/* Get the current end of the DSS. */
2181 		dss_max = sbrk(0);
2182 
2183 		/*
2184 		 * Try to shrink the DSS if this chunk is at the end of the
2185 		 * DSS.  The sbrk() call here is subject to a race condition
2186 		 * with threads that use brk(2) or sbrk(2) directly, but the
2187 		 * alternative would be to leak memory for the sake of poorly
2188 		 * designed multi-threaded programs.
2189 		 */
2190 		if ((void *)((uintptr_t)chunk + size) == dss_max
2191 		    && (dss_prev = sbrk(-(intptr_t)size)) == dss_max) {
2192 			/* Success. */
2193 			dss_max = (void *)((intptr_t)dss_prev - (intptr_t)size);
2194 
2195 			if (node != NULL) {
2196 				extent_tree_szad_remove(&dss_chunks_szad, node);
2197 				extent_tree_ad_remove(&dss_chunks_ad, node);
2198 				base_node_dealloc(node);
2199 			}
2200 		} else
2201 			madvise(chunk, size, MADV_FREE);
2202 
2203 		ret = false;
2204 		goto RETURN;
2205 	}
2206 
2207 	ret = true;
2208 RETURN:
2209 	malloc_mutex_unlock(&dss_mtx);
2210 	return (ret);
2211 }
2212 #endif
2213 
2214 static void
chunk_dealloc_mmap(void * chunk,size_t size)2215 chunk_dealloc_mmap(void *chunk, size_t size)
2216 {
2217 
2218 	pages_unmap(chunk, size);
2219 }
2220 
2221 static void
chunk_dealloc(void * chunk,size_t size)2222 chunk_dealloc(void *chunk, size_t size)
2223 {
2224 
2225 	assert(chunk != NULL);
2226 	assert(CHUNK_ADDR2BASE(chunk) == chunk);
2227 	assert(size != 0);
2228 	assert((size & chunksize_mask) == 0);
2229 
2230 #ifdef MALLOC_STATS
2231 	malloc_mutex_lock(&chunks_mtx);
2232 	stats_chunks.curchunks -= (size / chunksize);
2233 	malloc_mutex_unlock(&chunks_mtx);
2234 #endif
2235 
2236 #ifdef MALLOC_DSS
2237 	if (opt_dss) {
2238 		if (chunk_dealloc_dss(chunk, size) == false)
2239 			return;
2240 	}
2241 
2242 	if (opt_mmap)
2243 #endif
2244 		chunk_dealloc_mmap(chunk, size);
2245 }
2246 
2247 /*
2248  * End chunk management functions.
2249  */
2250 /******************************************************************************/
2251 /*
2252  * Begin arena.
2253  */
2254 
2255 /*
2256  * Choose an arena based on a per-thread value (fast-path code, calls slow-path
2257  * code if necessary).
2258  */
2259 static inline arena_t *
choose_arena(void)2260 choose_arena(void)
2261 {
2262 	arena_t *ret;
2263 
2264 	/*
2265 	 * We can only use TLS if this is a PIC library, since for the static
2266 	 * library version, libc's malloc is used by TLS allocation, which
2267 	 * introduces a bootstrapping issue.
2268 	 */
2269 #ifndef NO_TLS
2270 	if (__isthreaded == false) {
2271 	    /* Avoid the overhead of TLS for single-threaded operation. */
2272 	    return (arenas[0]);
2273 	}
2274 
2275 	ret = arenas_map;
2276 	if (ret == NULL) {
2277 		ret = choose_arena_hard();
2278 		assert(ret != NULL);
2279 	}
2280 #else
2281 	if (__isthreaded && narenas > 1) {
2282 		unsigned long ind;
2283 
2284 		/*
2285 		 * Hash _pthread_self() to one of the arenas.  There is a prime
2286 		 * number of arenas, so this has a reasonable chance of
2287 		 * working.  Even so, the hashing can be easily thwarted by
2288 		 * inconvenient _pthread_self() values.  Without specific
2289 		 * knowledge of how _pthread_self() calculates values, we can't
2290 		 * easily do much better than this.
2291 		 */
2292 		ind = (unsigned long) _pthread_self() % narenas;
2293 
2294 		/*
2295 		 * Optimistially assume that arenas[ind] has been initialized.
2296 		 * At worst, we find out that some other thread has already
2297 		 * done so, after acquiring the lock in preparation.  Note that
2298 		 * this lazy locking also has the effect of lazily forcing
2299 		 * cache coherency; without the lock acquisition, there's no
2300 		 * guarantee that modification of arenas[ind] by another thread
2301 		 * would be seen on this CPU for an arbitrary amount of time.
2302 		 *
2303 		 * In general, this approach to modifying a synchronized value
2304 		 * isn't a good idea, but in this case we only ever modify the
2305 		 * value once, so things work out well.
2306 		 */
2307 		ret = arenas[ind];
2308 		if (ret == NULL) {
2309 			/*
2310 			 * Avoid races with another thread that may have already
2311 			 * initialized arenas[ind].
2312 			 */
2313 			malloc_spin_lock(&arenas_lock);
2314 			if (arenas[ind] == NULL)
2315 				ret = arenas_extend((unsigned)ind);
2316 			else
2317 				ret = arenas[ind];
2318 			malloc_spin_unlock(&arenas_lock);
2319 		}
2320 	} else
2321 		ret = arenas[0];
2322 #endif
2323 
2324 	assert(ret != NULL);
2325 	return (ret);
2326 }
2327 
2328 #ifndef NO_TLS
2329 /*
2330  * Choose an arena based on a per-thread value (slow-path code only, called
2331  * only by choose_arena()).
2332  */
2333 static arena_t *
choose_arena_hard(void)2334 choose_arena_hard(void)
2335 {
2336 	arena_t *ret;
2337 
2338 	assert(__isthreaded);
2339 
2340 	if (narenas > 1) {
2341 		malloc_spin_lock(&arenas_lock);
2342 		if ((ret = arenas[next_arena]) == NULL)
2343 			ret = arenas_extend(next_arena);
2344 		next_arena = (next_arena + 1) % narenas;
2345 		malloc_spin_unlock(&arenas_lock);
2346 	} else
2347 		ret = arenas[0];
2348 
2349 	arenas_map = ret;
2350 
2351 	return (ret);
2352 }
2353 #endif
2354 
2355 static inline int
arena_chunk_comp(arena_chunk_t * a,arena_chunk_t * b)2356 arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
2357 {
2358 	uintptr_t a_chunk = (uintptr_t)a;
2359 	uintptr_t b_chunk = (uintptr_t)b;
2360 
2361 	assert(a != NULL);
2362 	assert(b != NULL);
2363 
2364 	return ((a_chunk > b_chunk) - (a_chunk < b_chunk));
2365 }
2366 
2367 /* Wrap red-black tree macros in functions. */
rb_gen(__unused static,arena_chunk_tree_dirty_,arena_chunk_tree_t,arena_chunk_t,link_dirty,arena_chunk_comp)2368 rb_gen(__unused static, arena_chunk_tree_dirty_, arena_chunk_tree_t,
2369     arena_chunk_t, link_dirty, arena_chunk_comp)
2370 
2371 static inline int
2372 arena_run_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
2373 {
2374 	uintptr_t a_mapelm = (uintptr_t)a;
2375 	uintptr_t b_mapelm = (uintptr_t)b;
2376 
2377 	assert(a != NULL);
2378 	assert(b != NULL);
2379 
2380 	return ((a_mapelm > b_mapelm) - (a_mapelm < b_mapelm));
2381 }
2382 
2383 /* Wrap red-black tree macros in functions. */
rb_gen(__unused static,arena_run_tree_,arena_run_tree_t,arena_chunk_map_t,link,arena_run_comp)2384 rb_gen(__unused static, arena_run_tree_, arena_run_tree_t, arena_chunk_map_t,
2385     link, arena_run_comp)
2386 
2387 static inline int
2388 arena_avail_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
2389 {
2390 	int ret;
2391 	size_t a_size = a->bits & ~PAGE_MASK;
2392 	size_t b_size = b->bits & ~PAGE_MASK;
2393 
2394 	ret = (a_size > b_size) - (a_size < b_size);
2395 	if (ret == 0) {
2396 		uintptr_t a_mapelm, b_mapelm;
2397 
2398 		if ((a->bits & CHUNK_MAP_KEY) != CHUNK_MAP_KEY)
2399 			a_mapelm = (uintptr_t)a;
2400 		else {
2401 			/*
2402 			 * Treat keys as though they are lower than anything
2403 			 * else.
2404 			 */
2405 			a_mapelm = 0;
2406 		}
2407 		b_mapelm = (uintptr_t)b;
2408 
2409 		ret = (a_mapelm > b_mapelm) - (a_mapelm < b_mapelm);
2410 	}
2411 
2412 	return (ret);
2413 }
2414 
2415 /* Wrap red-black tree macros in functions. */
rb_gen(__unused static,arena_avail_tree_,arena_avail_tree_t,arena_chunk_map_t,link,arena_avail_comp)2416 rb_gen(__unused static, arena_avail_tree_, arena_avail_tree_t,
2417     arena_chunk_map_t, link, arena_avail_comp)
2418 
2419 static inline void
2420 arena_run_rc_incr(arena_run_t *run, arena_bin_t *bin, const void *ptr)
2421 {
2422 	arena_chunk_t *chunk;
2423 	arena_t *arena;
2424 	size_t pagebeg, pageend, i;
2425 
2426 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
2427 	arena = chunk->arena;
2428 	pagebeg = ((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT;
2429 	pageend = ((uintptr_t)ptr + (uintptr_t)(bin->reg_size - 1) -
2430 	    (uintptr_t)chunk) >> PAGE_SHIFT;
2431 
2432 	for (i = pagebeg; i <= pageend; i++) {
2433 		size_t mapbits = chunk->map[i].bits;
2434 
2435 		if (mapbits & CHUNK_MAP_DIRTY) {
2436 			assert((mapbits & CHUNK_MAP_RC_MASK) == 0);
2437 			chunk->ndirty--;
2438 			arena->ndirty--;
2439 			mapbits ^= CHUNK_MAP_DIRTY;
2440 		}
2441 		assert((mapbits & CHUNK_MAP_RC_MASK) != CHUNK_MAP_RC_MASK);
2442 		mapbits += CHUNK_MAP_RC_ONE;
2443 		chunk->map[i].bits = mapbits;
2444 	}
2445 }
2446 
2447 static inline void
arena_run_rc_decr(arena_run_t * run,arena_bin_t * bin,const void * ptr)2448 arena_run_rc_decr(arena_run_t *run, arena_bin_t *bin, const void *ptr)
2449 {
2450 	arena_chunk_t *chunk;
2451 	arena_t *arena;
2452 	size_t pagebeg, pageend, mapbits, i;
2453 	bool dirtier = false;
2454 
2455 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
2456 	arena = chunk->arena;
2457 	pagebeg = ((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT;
2458 	pageend = ((uintptr_t)ptr + (uintptr_t)(bin->reg_size - 1) -
2459 	    (uintptr_t)chunk) >> PAGE_SHIFT;
2460 
2461 	/* First page. */
2462 	mapbits = chunk->map[pagebeg].bits;
2463 	mapbits -= CHUNK_MAP_RC_ONE;
2464 	if ((mapbits & CHUNK_MAP_RC_MASK) == 0) {
2465 		dirtier = true;
2466 		assert((mapbits & CHUNK_MAP_DIRTY) == 0);
2467 		mapbits |= CHUNK_MAP_DIRTY;
2468 		chunk->ndirty++;
2469 		arena->ndirty++;
2470 	}
2471 	chunk->map[pagebeg].bits = mapbits;
2472 
2473 	if (pageend - pagebeg >= 1) {
2474 		/*
2475 		 * Interior pages are completely consumed by the object being
2476 		 * deallocated, which means that the pages can be
2477 		 * unconditionally marked dirty.
2478 		 */
2479 		for (i = pagebeg + 1; i < pageend; i++) {
2480 			mapbits = chunk->map[i].bits;
2481 			mapbits -= CHUNK_MAP_RC_ONE;
2482 			assert((mapbits & CHUNK_MAP_RC_MASK) == 0);
2483 			dirtier = true;
2484 			assert((mapbits & CHUNK_MAP_DIRTY) == 0);
2485 			mapbits |= CHUNK_MAP_DIRTY;
2486 			chunk->ndirty++;
2487 			arena->ndirty++;
2488 			chunk->map[i].bits = mapbits;
2489 		}
2490 
2491 		/* Last page. */
2492 		mapbits = chunk->map[pageend].bits;
2493 		mapbits -= CHUNK_MAP_RC_ONE;
2494 		if ((mapbits & CHUNK_MAP_RC_MASK) == 0) {
2495 			dirtier = true;
2496 			assert((mapbits & CHUNK_MAP_DIRTY) == 0);
2497 			mapbits |= CHUNK_MAP_DIRTY;
2498 			chunk->ndirty++;
2499 			arena->ndirty++;
2500 		}
2501 		chunk->map[pageend].bits = mapbits;
2502 	}
2503 
2504 	if (dirtier) {
2505 		if (chunk->dirtied == false) {
2506 			arena_chunk_tree_dirty_insert(&arena->chunks_dirty,
2507 			    chunk);
2508 			chunk->dirtied = true;
2509 		}
2510 
2511 		/* Enforce opt_lg_dirty_mult. */
2512 		if (opt_lg_dirty_mult >= 0 && (arena->nactive >>
2513 		    opt_lg_dirty_mult) < arena->ndirty)
2514 			arena_purge(arena);
2515 	}
2516 }
2517 
2518 static inline void *
arena_run_reg_alloc(arena_run_t * run,arena_bin_t * bin)2519 arena_run_reg_alloc(arena_run_t *run, arena_bin_t *bin)
2520 {
2521 	void *ret;
2522 	unsigned i, mask, bit, regind;
2523 
2524 	assert(run->magic == ARENA_RUN_MAGIC);
2525 	assert(run->regs_minelm < bin->regs_mask_nelms);
2526 
2527 	/*
2528 	 * Move the first check outside the loop, so that run->regs_minelm can
2529 	 * be updated unconditionally, without the possibility of updating it
2530 	 * multiple times.
2531 	 */
2532 	i = run->regs_minelm;
2533 	mask = run->regs_mask[i];
2534 	if (mask != 0) {
2535 		/* Usable allocation found. */
2536 		bit = ffs((int)mask) - 1;
2537 
2538 		regind = ((i << (LG_SIZEOF_INT + 3)) + bit);
2539 		assert(regind < bin->nregs);
2540 		ret = (void *)(((uintptr_t)run) + bin->reg0_offset
2541 		    + (bin->reg_size * regind));
2542 
2543 		/* Clear bit. */
2544 		mask ^= (1U << bit);
2545 		run->regs_mask[i] = mask;
2546 
2547 		arena_run_rc_incr(run, bin, ret);
2548 
2549 		return (ret);
2550 	}
2551 
2552 	for (i++; i < bin->regs_mask_nelms; i++) {
2553 		mask = run->regs_mask[i];
2554 		if (mask != 0) {
2555 			/* Usable allocation found. */
2556 			bit = ffs((int)mask) - 1;
2557 
2558 			regind = ((i << (LG_SIZEOF_INT + 3)) + bit);
2559 			assert(regind < bin->nregs);
2560 			ret = (void *)(((uintptr_t)run) + bin->reg0_offset
2561 			    + (bin->reg_size * regind));
2562 
2563 			/* Clear bit. */
2564 			mask ^= (1U << bit);
2565 			run->regs_mask[i] = mask;
2566 
2567 			/*
2568 			 * Make a note that nothing before this element
2569 			 * contains a free region.
2570 			 */
2571 			run->regs_minelm = i; /* Low payoff: + (mask == 0); */
2572 
2573 			arena_run_rc_incr(run, bin, ret);
2574 
2575 			return (ret);
2576 		}
2577 	}
2578 	/* Not reached. */
2579 	assert(0);
2580 	return (NULL);
2581 }
2582 
2583 static inline void
arena_run_reg_dalloc(arena_run_t * run,arena_bin_t * bin,void * ptr,size_t size)2584 arena_run_reg_dalloc(arena_run_t *run, arena_bin_t *bin, void *ptr, size_t size)
2585 {
2586 	unsigned shift, diff, regind, elm, bit;
2587 
2588 	assert(run->magic == ARENA_RUN_MAGIC);
2589 
2590 	/*
2591 	 * Avoid doing division with a variable divisor if possible.  Using
2592 	 * actual division here can reduce allocator throughput by over 20%!
2593 	 */
2594 	diff = (unsigned)((uintptr_t)ptr - (uintptr_t)run - bin->reg0_offset);
2595 
2596 	/* Rescale (factor powers of 2 out of the numerator and denominator). */
2597 	shift = ffs(size) - 1;
2598 	diff >>= shift;
2599 	size >>= shift;
2600 
2601 	if (size == 1) {
2602 		/* The divisor was a power of 2. */
2603 		regind = diff;
2604 	} else {
2605 		/*
2606 		 * To divide by a number D that is not a power of two we
2607 		 * multiply by (2^21 / D) and then right shift by 21 positions.
2608 		 *
2609 		 *   X / D
2610 		 *
2611 		 * becomes
2612 		 *
2613 		 *   (X * size_invs[D - 3]) >> SIZE_INV_SHIFT
2614 		 *
2615 		 * We can omit the first three elements, because we never
2616 		 * divide by 0, and 1 and 2 are both powers of two, which are
2617 		 * handled above.
2618 		 */
2619 #define	SIZE_INV_SHIFT 21
2620 #define	SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s)) + 1)
2621 		static const unsigned size_invs[] = {
2622 		    SIZE_INV(3),
2623 		    SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
2624 		    SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
2625 		    SIZE_INV(12), SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
2626 		    SIZE_INV(16), SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
2627 		    SIZE_INV(20), SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
2628 		    SIZE_INV(24), SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
2629 		    SIZE_INV(28), SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
2630 		};
2631 
2632 		if (size <= ((sizeof(size_invs) / sizeof(unsigned)) + 2))
2633 			regind = (diff * size_invs[size - 3]) >> SIZE_INV_SHIFT;
2634 		else
2635 			regind = diff / size;
2636 #undef SIZE_INV
2637 #undef SIZE_INV_SHIFT
2638 	}
2639 	assert(diff == regind * size);
2640 	assert(regind < bin->nregs);
2641 
2642 	elm = regind >> (LG_SIZEOF_INT + 3);
2643 	if (elm < run->regs_minelm)
2644 		run->regs_minelm = elm;
2645 	bit = regind - (elm << (LG_SIZEOF_INT + 3));
2646 	assert((run->regs_mask[elm] & (1U << bit)) == 0);
2647 	run->regs_mask[elm] |= (1U << bit);
2648 
2649 	arena_run_rc_decr(run, bin, ptr);
2650 }
2651 
2652 static void
arena_run_split(arena_t * arena,arena_run_t * run,size_t size,bool large,bool zero)2653 arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large,
2654     bool zero)
2655 {
2656 	arena_chunk_t *chunk;
2657 	size_t old_ndirty, run_ind, total_pages, need_pages, rem_pages, i;
2658 
2659 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
2660 	old_ndirty = chunk->ndirty;
2661 	run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
2662 	    >> PAGE_SHIFT);
2663 	total_pages = (chunk->map[run_ind].bits & ~PAGE_MASK) >>
2664 	    PAGE_SHIFT;
2665 	need_pages = (size >> PAGE_SHIFT);
2666 	assert(need_pages > 0);
2667 	assert(need_pages <= total_pages);
2668 	rem_pages = total_pages - need_pages;
2669 
2670 	arena_avail_tree_remove(&arena->runs_avail, &chunk->map[run_ind]);
2671 	arena->nactive += need_pages;
2672 
2673 	/* Keep track of trailing unused pages for later use. */
2674 	if (rem_pages > 0) {
2675 		chunk->map[run_ind+need_pages].bits = (rem_pages <<
2676 		    PAGE_SHIFT) | (chunk->map[run_ind+need_pages].bits &
2677 		    CHUNK_MAP_FLAGS_MASK);
2678 		chunk->map[run_ind+total_pages-1].bits = (rem_pages <<
2679 		    PAGE_SHIFT) | (chunk->map[run_ind+total_pages-1].bits &
2680 		    CHUNK_MAP_FLAGS_MASK);
2681 		arena_avail_tree_insert(&arena->runs_avail,
2682 		    &chunk->map[run_ind+need_pages]);
2683 	}
2684 
2685 	for (i = 0; i < need_pages; i++) {
2686 		/* Zero if necessary. */
2687 		if (zero) {
2688 			if ((chunk->map[run_ind + i].bits & CHUNK_MAP_ZEROED)
2689 			    == 0) {
2690 				memset((void *)((uintptr_t)chunk + ((run_ind
2691 				    + i) << PAGE_SHIFT)), 0, PAGE_SIZE);
2692 				/* CHUNK_MAP_ZEROED is cleared below. */
2693 			}
2694 		}
2695 
2696 		/* Update dirty page accounting. */
2697 		if (chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY) {
2698 			chunk->ndirty--;
2699 			arena->ndirty--;
2700 			/* CHUNK_MAP_DIRTY is cleared below. */
2701 		}
2702 
2703 		/* Initialize the chunk map. */
2704 		if (large) {
2705 			chunk->map[run_ind + i].bits = CHUNK_MAP_LARGE
2706 			    | CHUNK_MAP_ALLOCATED;
2707 		} else {
2708 			chunk->map[run_ind + i].bits = (i << CHUNK_MAP_PG_SHIFT)
2709 			    | CHUNK_MAP_ALLOCATED;
2710 		}
2711 	}
2712 
2713 	if (large) {
2714 		/*
2715 		 * Set the run size only in the first element for large runs.
2716 		 * This is primarily a debugging aid, since the lack of size
2717 		 * info for trailing pages only matters if the application
2718 		 * tries to operate on an interior pointer.
2719 		 */
2720 		chunk->map[run_ind].bits |= size;
2721 	} else {
2722 		/*
2723 		 * Initialize the first page's refcount to 1, so that the run
2724 		 * header is protected from dirty page purging.
2725 		 */
2726 		chunk->map[run_ind].bits += CHUNK_MAP_RC_ONE;
2727 	}
2728 }
2729 
2730 static arena_chunk_t *
arena_chunk_alloc(arena_t * arena)2731 arena_chunk_alloc(arena_t *arena)
2732 {
2733 	arena_chunk_t *chunk;
2734 	size_t i;
2735 
2736 	if (arena->spare != NULL) {
2737 		chunk = arena->spare;
2738 		arena->spare = NULL;
2739 	} else {
2740 		bool zero;
2741 		size_t zeroed;
2742 
2743 		zero = false;
2744 		chunk = (arena_chunk_t *)chunk_alloc(chunksize, &zero);
2745 		if (chunk == NULL)
2746 			return (NULL);
2747 #ifdef MALLOC_STATS
2748 		arena->stats.mapped += chunksize;
2749 #endif
2750 
2751 		chunk->arena = arena;
2752 		chunk->dirtied = false;
2753 
2754 		/*
2755 		 * Claim that no pages are in use, since the header is merely
2756 		 * overhead.
2757 		 */
2758 		chunk->ndirty = 0;
2759 
2760 		/*
2761 		 * Initialize the map to contain one maximal free untouched run.
2762 		 * Mark the pages as zeroed iff chunk_alloc() returned a zeroed
2763 		 * chunk.
2764 		 */
2765 		zeroed = zero ? CHUNK_MAP_ZEROED : 0;
2766 		for (i = 0; i < arena_chunk_header_npages; i++)
2767 			chunk->map[i].bits = 0;
2768 		chunk->map[i].bits = arena_maxclass | zeroed;
2769 		for (i++; i < chunk_npages-1; i++)
2770 			chunk->map[i].bits = zeroed;
2771 		chunk->map[chunk_npages-1].bits = arena_maxclass | zeroed;
2772 	}
2773 
2774 	/* Insert the run into the runs_avail tree. */
2775 	arena_avail_tree_insert(&arena->runs_avail,
2776 	    &chunk->map[arena_chunk_header_npages]);
2777 
2778 	return (chunk);
2779 }
2780 
2781 static void
arena_chunk_dealloc(arena_t * arena,arena_chunk_t * chunk)2782 arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
2783 {
2784 
2785 	if (arena->spare != NULL) {
2786 		if (arena->spare->dirtied) {
2787 			arena_chunk_tree_dirty_remove(
2788 			    &chunk->arena->chunks_dirty, arena->spare);
2789 			arena->ndirty -= arena->spare->ndirty;
2790 		}
2791 		chunk_dealloc((void *)arena->spare, chunksize);
2792 #ifdef MALLOC_STATS
2793 		arena->stats.mapped -= chunksize;
2794 #endif
2795 	}
2796 
2797 	/*
2798 	 * Remove run from runs_avail, regardless of whether this chunk
2799 	 * will be cached, so that the arena does not use it.  Dirty page
2800 	 * flushing only uses the chunks_dirty tree, so leaving this chunk in
2801 	 * the chunks_* trees is sufficient for that purpose.
2802 	 */
2803 	arena_avail_tree_remove(&arena->runs_avail,
2804 	    &chunk->map[arena_chunk_header_npages]);
2805 
2806 	arena->spare = chunk;
2807 }
2808 
2809 static arena_run_t *
arena_run_alloc(arena_t * arena,size_t size,bool large,bool zero)2810 arena_run_alloc(arena_t *arena, size_t size, bool large, bool zero)
2811 {
2812 	arena_chunk_t *chunk;
2813 	arena_run_t *run;
2814 	arena_chunk_map_t *mapelm, key;
2815 
2816 	assert(size <= arena_maxclass);
2817 	assert((size & PAGE_MASK) == 0);
2818 
2819 	/* Search the arena's chunks for the lowest best fit. */
2820 	key.bits = size | CHUNK_MAP_KEY;
2821 	mapelm = arena_avail_tree_nsearch(&arena->runs_avail, &key);
2822 	if (mapelm != NULL) {
2823 		arena_chunk_t *run_chunk = CHUNK_ADDR2BASE(mapelm);
2824 		size_t pageind = ((uintptr_t)mapelm - (uintptr_t)run_chunk->map)
2825 		    / sizeof(arena_chunk_map_t);
2826 
2827 		run = (arena_run_t *)((uintptr_t)run_chunk + (pageind
2828 		    << PAGE_SHIFT));
2829 		arena_run_split(arena, run, size, large, zero);
2830 		return (run);
2831 	}
2832 
2833 	/*
2834 	 * No usable runs.  Create a new chunk from which to allocate the run.
2835 	 */
2836 	chunk = arena_chunk_alloc(arena);
2837 	if (chunk == NULL)
2838 		return (NULL);
2839 	run = (arena_run_t *)((uintptr_t)chunk + (arena_chunk_header_npages <<
2840 	    PAGE_SHIFT));
2841 	/* Update page map. */
2842 	arena_run_split(arena, run, size, large, zero);
2843 	return (run);
2844 }
2845 
2846 #ifdef MALLOC_DEBUG
2847 static arena_chunk_t *
chunks_dirty_iter_cb(arena_chunk_tree_t * tree,arena_chunk_t * chunk,void * arg)2848 chunks_dirty_iter_cb(arena_chunk_tree_t *tree, arena_chunk_t *chunk, void *arg)
2849 {
2850 	size_t *ndirty = (size_t *)arg;
2851 
2852 	assert(chunk->dirtied);
2853 	*ndirty += chunk->ndirty;
2854 	return (NULL);
2855 }
2856 #endif
2857 
2858 static void
arena_purge(arena_t * arena)2859 arena_purge(arena_t *arena)
2860 {
2861 	arena_chunk_t *chunk;
2862 	size_t i, npages;
2863 #ifdef MALLOC_DEBUG
2864 	size_t ndirty = 0;
2865 
2866 	arena_chunk_tree_dirty_iter(&arena->chunks_dirty, NULL,
2867 	    chunks_dirty_iter_cb, (void *)&ndirty);
2868 	assert(ndirty == arena->ndirty);
2869 #endif
2870 	assert((arena->nactive >> opt_lg_dirty_mult) < arena->ndirty);
2871 
2872 #ifdef MALLOC_STATS
2873 	arena->stats.npurge++;
2874 #endif
2875 
2876 	/*
2877 	 * Iterate downward through chunks until enough dirty memory has been
2878 	 * purged.  Terminate as soon as possible in order to minimize the
2879 	 * number of system calls, even if a chunk has only been partially
2880 	 * purged.
2881 	 */
2882 
2883 	while ((arena->nactive >> (opt_lg_dirty_mult + 1)) < arena->ndirty) {
2884 		chunk = arena_chunk_tree_dirty_last(&arena->chunks_dirty);
2885 		assert(chunk != NULL);
2886 
2887 		for (i = chunk_npages - 1; chunk->ndirty > 0; i--) {
2888 			assert(i >= arena_chunk_header_npages);
2889 			if (chunk->map[i].bits & CHUNK_MAP_DIRTY) {
2890 				chunk->map[i].bits ^= CHUNK_MAP_DIRTY;
2891 				/* Find adjacent dirty run(s). */
2892 				for (npages = 1; i > arena_chunk_header_npages
2893 				    && (chunk->map[i - 1].bits &
2894 				    CHUNK_MAP_DIRTY); npages++) {
2895 					i--;
2896 					chunk->map[i].bits ^= CHUNK_MAP_DIRTY;
2897 				}
2898 				chunk->ndirty -= npages;
2899 				arena->ndirty -= npages;
2900 
2901 				madvise((void *)((uintptr_t)chunk + (i <<
2902 				    PAGE_SHIFT)), (npages << PAGE_SHIFT),
2903 				    MADV_FREE);
2904 #ifdef MALLOC_STATS
2905 				arena->stats.nmadvise++;
2906 				arena->stats.purged += npages;
2907 #endif
2908 				if ((arena->nactive >> (opt_lg_dirty_mult + 1))
2909 				    >= arena->ndirty)
2910 					break;
2911 			}
2912 		}
2913 
2914 		if (chunk->ndirty == 0) {
2915 			arena_chunk_tree_dirty_remove(&arena->chunks_dirty,
2916 			    chunk);
2917 			chunk->dirtied = false;
2918 		}
2919 	}
2920 }
2921 
2922 static void
arena_run_dalloc(arena_t * arena,arena_run_t * run,bool dirty)2923 arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty)
2924 {
2925 	arena_chunk_t *chunk;
2926 	size_t size, run_ind, run_pages;
2927 
2928 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
2929 	run_ind = (size_t)(((uintptr_t)run - (uintptr_t)chunk)
2930 	    >> PAGE_SHIFT);
2931 	assert(run_ind >= arena_chunk_header_npages);
2932 	assert(run_ind < chunk_npages);
2933 	if ((chunk->map[run_ind].bits & CHUNK_MAP_LARGE) != 0)
2934 		size = chunk->map[run_ind].bits & ~PAGE_MASK;
2935 	else
2936 		size = run->bin->run_size;
2937 	run_pages = (size >> PAGE_SHIFT);
2938 	arena->nactive -= run_pages;
2939 
2940 	/* Mark pages as unallocated in the chunk map. */
2941 	if (dirty) {
2942 		size_t i;
2943 
2944 		for (i = 0; i < run_pages; i++) {
2945 			/*
2946 			 * When (dirty == true), *all* pages within the run
2947 			 * need to have their dirty bits set, because only
2948 			 * small runs can create a mixture of clean/dirty
2949 			 * pages, but such runs are passed to this function
2950 			 * with (dirty == false).
2951 			 */
2952 			assert((chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY)
2953 			    == 0);
2954 			chunk->ndirty++;
2955 			arena->ndirty++;
2956 			chunk->map[run_ind + i].bits = CHUNK_MAP_DIRTY;
2957 		}
2958 	} else {
2959 		size_t i;
2960 
2961 		for (i = 0; i < run_pages; i++) {
2962 			chunk->map[run_ind + i].bits &= ~(CHUNK_MAP_LARGE |
2963 			    CHUNK_MAP_ALLOCATED);
2964 		}
2965 	}
2966 	chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
2967 	    CHUNK_MAP_FLAGS_MASK);
2968 	chunk->map[run_ind+run_pages-1].bits = size |
2969 	    (chunk->map[run_ind+run_pages-1].bits & CHUNK_MAP_FLAGS_MASK);
2970 
2971 	/* Try to coalesce forward. */
2972 	if (run_ind + run_pages < chunk_npages &&
2973 	    (chunk->map[run_ind+run_pages].bits & CHUNK_MAP_ALLOCATED) == 0) {
2974 		size_t nrun_size = chunk->map[run_ind+run_pages].bits &
2975 		    ~PAGE_MASK;
2976 
2977 		/*
2978 		 * Remove successor from runs_avail; the coalesced run is
2979 		 * inserted later.
2980 		 */
2981 		arena_avail_tree_remove(&arena->runs_avail,
2982 		    &chunk->map[run_ind+run_pages]);
2983 
2984 		size += nrun_size;
2985 		run_pages = size >> PAGE_SHIFT;
2986 
2987 		assert((chunk->map[run_ind+run_pages-1].bits & ~PAGE_MASK)
2988 		    == nrun_size);
2989 		chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
2990 		    CHUNK_MAP_FLAGS_MASK);
2991 		chunk->map[run_ind+run_pages-1].bits = size |
2992 		    (chunk->map[run_ind+run_pages-1].bits &
2993 		    CHUNK_MAP_FLAGS_MASK);
2994 	}
2995 
2996 	/* Try to coalesce backward. */
2997 	if (run_ind > arena_chunk_header_npages && (chunk->map[run_ind-1].bits &
2998 	    CHUNK_MAP_ALLOCATED) == 0) {
2999 		size_t prun_size = chunk->map[run_ind-1].bits & ~PAGE_MASK;
3000 
3001 		run_ind -= prun_size >> PAGE_SHIFT;
3002 
3003 		/*
3004 		 * Remove predecessor from runs_avail; the coalesced run is
3005 		 * inserted later.
3006 		 */
3007 		arena_avail_tree_remove(&arena->runs_avail,
3008 		    &chunk->map[run_ind]);
3009 
3010 		size += prun_size;
3011 		run_pages = size >> PAGE_SHIFT;
3012 
3013 		assert((chunk->map[run_ind].bits & ~PAGE_MASK) == prun_size);
3014 		chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
3015 		    CHUNK_MAP_FLAGS_MASK);
3016 		chunk->map[run_ind+run_pages-1].bits = size |
3017 		    (chunk->map[run_ind+run_pages-1].bits &
3018 		    CHUNK_MAP_FLAGS_MASK);
3019 	}
3020 
3021 	/* Insert into runs_avail, now that coalescing is complete. */
3022 	arena_avail_tree_insert(&arena->runs_avail, &chunk->map[run_ind]);
3023 
3024 	/*
3025 	 * Deallocate chunk if it is now completely unused.  The bit
3026 	 * manipulation checks whether the first run is unallocated and extends
3027 	 * to the end of the chunk.
3028 	 */
3029 	if ((chunk->map[arena_chunk_header_npages].bits & (~PAGE_MASK |
3030 	    CHUNK_MAP_ALLOCATED)) == arena_maxclass)
3031 		arena_chunk_dealloc(arena, chunk);
3032 
3033 	/*
3034 	 * It is okay to do dirty page processing even if the chunk was
3035 	 * deallocated above, since in that case it is the spare.  Waiting
3036 	 * until after possible chunk deallocation to do dirty processing
3037 	 * allows for an old spare to be fully deallocated, thus decreasing the
3038 	 * chances of spuriously crossing the dirty page purging threshold.
3039 	 */
3040 	if (dirty) {
3041 		if (chunk->dirtied == false) {
3042 			arena_chunk_tree_dirty_insert(&arena->chunks_dirty,
3043 			    chunk);
3044 			chunk->dirtied = true;
3045 		}
3046 
3047 		/* Enforce opt_lg_dirty_mult. */
3048 		if (opt_lg_dirty_mult >= 0 && (arena->nactive >>
3049 		    opt_lg_dirty_mult) < arena->ndirty)
3050 			arena_purge(arena);
3051 	}
3052 }
3053 
3054 static void
arena_run_trim_head(arena_t * arena,arena_chunk_t * chunk,arena_run_t * run,size_t oldsize,size_t newsize)3055 arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
3056     size_t oldsize, size_t newsize)
3057 {
3058 	size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> PAGE_SHIFT;
3059 	size_t head_npages = (oldsize - newsize) >> PAGE_SHIFT;
3060 
3061 	assert(oldsize > newsize);
3062 
3063 	/*
3064 	 * Update the chunk map so that arena_run_dalloc() can treat the
3065 	 * leading run as separately allocated.
3066 	 */
3067 	assert((chunk->map[pageind].bits & CHUNK_MAP_DIRTY) == 0);
3068 	chunk->map[pageind].bits = (oldsize - newsize) | CHUNK_MAP_LARGE |
3069 	    CHUNK_MAP_ALLOCATED;
3070 	assert((chunk->map[pageind+head_npages].bits & CHUNK_MAP_DIRTY) == 0);
3071 	chunk->map[pageind+head_npages].bits = newsize | CHUNK_MAP_LARGE |
3072 	    CHUNK_MAP_ALLOCATED;
3073 
3074 	arena_run_dalloc(arena, run, false);
3075 }
3076 
3077 static void
arena_run_trim_tail(arena_t * arena,arena_chunk_t * chunk,arena_run_t * run,size_t oldsize,size_t newsize,bool dirty)3078 arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
3079     size_t oldsize, size_t newsize, bool dirty)
3080 {
3081 	size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> PAGE_SHIFT;
3082 	size_t npages = newsize >> PAGE_SHIFT;
3083 
3084 	assert(oldsize > newsize);
3085 
3086 	/*
3087 	 * Update the chunk map so that arena_run_dalloc() can treat the
3088 	 * trailing run as separately allocated.
3089 	 */
3090 	assert((chunk->map[pageind].bits & CHUNK_MAP_DIRTY) == 0);
3091 	chunk->map[pageind].bits = newsize | CHUNK_MAP_LARGE |
3092 	    CHUNK_MAP_ALLOCATED;
3093 	assert((chunk->map[pageind+npages].bits & CHUNK_MAP_DIRTY) == 0);
3094 	chunk->map[pageind+npages].bits = (oldsize - newsize) | CHUNK_MAP_LARGE
3095 	    | CHUNK_MAP_ALLOCATED;
3096 
3097 	arena_run_dalloc(arena, (arena_run_t *)((uintptr_t)run + newsize),
3098 	    dirty);
3099 }
3100 
3101 static arena_run_t *
arena_bin_nonfull_run_get(arena_t * arena,arena_bin_t * bin)3102 arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
3103 {
3104 	arena_chunk_map_t *mapelm;
3105 	arena_run_t *run;
3106 	unsigned i, remainder;
3107 
3108 	/* Look for a usable run. */
3109 	mapelm = arena_run_tree_first(&bin->runs);
3110 	if (mapelm != NULL) {
3111 		arena_chunk_t *chunk;
3112 		size_t pageind;
3113 
3114 		/* run is guaranteed to have available space. */
3115 		arena_run_tree_remove(&bin->runs, mapelm);
3116 
3117 		chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(mapelm);
3118 		pageind = (((uintptr_t)mapelm - (uintptr_t)chunk->map) /
3119 		    sizeof(arena_chunk_map_t));
3120 		run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
3121 		    ((mapelm->bits & CHUNK_MAP_PG_MASK) >> CHUNK_MAP_PG_SHIFT))
3122 		    << PAGE_SHIFT));
3123 #ifdef MALLOC_STATS
3124 		bin->stats.reruns++;
3125 #endif
3126 		return (run);
3127 	}
3128 	/* No existing runs have any space available. */
3129 
3130 	/* Allocate a new run. */
3131 	run = arena_run_alloc(arena, bin->run_size, false, false);
3132 	if (run == NULL)
3133 		return (NULL);
3134 
3135 	/* Initialize run internals. */
3136 	run->bin = bin;
3137 
3138 	for (i = 0; i < bin->regs_mask_nelms - 1; i++)
3139 		run->regs_mask[i] = UINT_MAX;
3140 	remainder = bin->nregs & ((1U << (LG_SIZEOF_INT + 3)) - 1);
3141 	if (remainder == 0)
3142 		run->regs_mask[i] = UINT_MAX;
3143 	else {
3144 		/* The last element has spare bits that need to be unset. */
3145 		run->regs_mask[i] = (UINT_MAX >> ((1U << (LG_SIZEOF_INT + 3))
3146 		    - remainder));
3147 	}
3148 
3149 	run->regs_minelm = 0;
3150 
3151 	run->nfree = bin->nregs;
3152 #ifdef MALLOC_DEBUG
3153 	run->magic = ARENA_RUN_MAGIC;
3154 #endif
3155 
3156 #ifdef MALLOC_STATS
3157 	bin->stats.nruns++;
3158 	bin->stats.curruns++;
3159 	if (bin->stats.curruns > bin->stats.highruns)
3160 		bin->stats.highruns = bin->stats.curruns;
3161 #endif
3162 	return (run);
3163 }
3164 
3165 /* bin->runcur must have space available before this function is called. */
3166 static inline void *
arena_bin_malloc_easy(arena_t * arena,arena_bin_t * bin,arena_run_t * run)3167 arena_bin_malloc_easy(arena_t *arena, arena_bin_t *bin, arena_run_t *run)
3168 {
3169 	void *ret;
3170 
3171 	assert(run->magic == ARENA_RUN_MAGIC);
3172 	assert(run->nfree > 0);
3173 
3174 	ret = arena_run_reg_alloc(run, bin);
3175 	assert(ret != NULL);
3176 	run->nfree--;
3177 
3178 	return (ret);
3179 }
3180 
3181 /* Re-fill bin->runcur, then call arena_bin_malloc_easy(). */
3182 static void *
arena_bin_malloc_hard(arena_t * arena,arena_bin_t * bin)3183 arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
3184 {
3185 
3186 	bin->runcur = arena_bin_nonfull_run_get(arena, bin);
3187 	if (bin->runcur == NULL)
3188 		return (NULL);
3189 	assert(bin->runcur->magic == ARENA_RUN_MAGIC);
3190 	assert(bin->runcur->nfree > 0);
3191 
3192 	return (arena_bin_malloc_easy(arena, bin, bin->runcur));
3193 }
3194 
3195 /*
3196  * Calculate bin->run_size such that it meets the following constraints:
3197  *
3198  *   *) bin->run_size >= min_run_size
3199  *   *) bin->run_size <= arena_maxclass
3200  *   *) bin->run_size <= RUN_MAX_SMALL
3201  *   *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
3202  *   *) run header size < PAGE_SIZE
3203  *
3204  * bin->nregs, bin->regs_mask_nelms, and bin->reg0_offset are
3205  * also calculated here, since these settings are all interdependent.
3206  */
3207 static size_t
arena_bin_run_size_calc(arena_bin_t * bin,size_t min_run_size)3208 arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
3209 {
3210 	size_t try_run_size, good_run_size;
3211 	unsigned good_nregs, good_mask_nelms, good_reg0_offset;
3212 	unsigned try_nregs, try_mask_nelms, try_reg0_offset;
3213 
3214 	assert(min_run_size >= PAGE_SIZE);
3215 	assert(min_run_size <= arena_maxclass);
3216 	assert(min_run_size <= RUN_MAX_SMALL);
3217 
3218 	/*
3219 	 * Calculate known-valid settings before entering the run_size
3220 	 * expansion loop, so that the first part of the loop always copies
3221 	 * valid settings.
3222 	 *
3223 	 * The do..while loop iteratively reduces the number of regions until
3224 	 * the run header and the regions no longer overlap.  A closed formula
3225 	 * would be quite messy, since there is an interdependency between the
3226 	 * header's mask length and the number of regions.
3227 	 */
3228 	try_run_size = min_run_size;
3229 	try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin->reg_size)
3230 	    + 1; /* Counter-act try_nregs-- in loop. */
3231 	do {
3232 		try_nregs--;
3233 		try_mask_nelms = (try_nregs >> (LG_SIZEOF_INT + 3)) +
3234 		    ((try_nregs & ((1U << (LG_SIZEOF_INT + 3)) - 1)) ? 1 : 0);
3235 		try_reg0_offset = try_run_size - (try_nregs * bin->reg_size);
3236 	} while (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1))
3237 	    > try_reg0_offset);
3238 
3239 	/* run_size expansion loop. */
3240 	do {
3241 		/*
3242 		 * Copy valid settings before trying more aggressive settings.
3243 		 */
3244 		good_run_size = try_run_size;
3245 		good_nregs = try_nregs;
3246 		good_mask_nelms = try_mask_nelms;
3247 		good_reg0_offset = try_reg0_offset;
3248 
3249 		/* Try more aggressive settings. */
3250 		try_run_size += PAGE_SIZE;
3251 		try_nregs = ((try_run_size - sizeof(arena_run_t)) /
3252 		    bin->reg_size) + 1; /* Counter-act try_nregs-- in loop. */
3253 		do {
3254 			try_nregs--;
3255 			try_mask_nelms = (try_nregs >> (LG_SIZEOF_INT + 3)) +
3256 			    ((try_nregs & ((1U << (LG_SIZEOF_INT + 3)) - 1)) ?
3257 			    1 : 0);
3258 			try_reg0_offset = try_run_size - (try_nregs *
3259 			    bin->reg_size);
3260 		} while (sizeof(arena_run_t) + (sizeof(unsigned) *
3261 		    (try_mask_nelms - 1)) > try_reg0_offset);
3262 	} while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL
3263 	    && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
3264 	    && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size
3265 	    && (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1)))
3266 	    < PAGE_SIZE);
3267 
3268 	assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
3269 	    <= good_reg0_offset);
3270 	assert((good_mask_nelms << (LG_SIZEOF_INT + 3)) >= good_nregs);
3271 
3272 	/* Copy final settings. */
3273 	bin->run_size = good_run_size;
3274 	bin->nregs = good_nregs;
3275 	bin->regs_mask_nelms = good_mask_nelms;
3276 	bin->reg0_offset = good_reg0_offset;
3277 
3278 	return (good_run_size);
3279 }
3280 
3281 #ifdef MALLOC_TCACHE
3282 static inline void
tcache_event(tcache_t * tcache)3283 tcache_event(tcache_t *tcache)
3284 {
3285 
3286 	if (tcache_gc_incr == 0)
3287 		return;
3288 
3289 	tcache->ev_cnt++;
3290 	assert(tcache->ev_cnt <= tcache_gc_incr);
3291 	if (tcache->ev_cnt >= tcache_gc_incr) {
3292 		size_t binind = tcache->next_gc_bin;
3293 		tcache_bin_t *tbin = tcache->tbins[binind];
3294 
3295 		if (tbin != NULL) {
3296 			if (tbin->high_water == 0) {
3297 				/*
3298 				 * This bin went completely unused for an
3299 				 * entire GC cycle, so throw away the tbin.
3300 				 */
3301 				assert(tbin->ncached == 0);
3302 				tcache_bin_destroy(tcache, tbin, binind);
3303 				tcache->tbins[binind] = NULL;
3304 			} else {
3305 				if (tbin->low_water > 0) {
3306 					/*
3307 					 * Flush (ceiling) half of the objects
3308 					 * below the low water mark.
3309 					 */
3310 					tcache_bin_flush(tbin, binind,
3311 					    tbin->ncached - (tbin->low_water >>
3312 					    1) - (tbin->low_water & 1));
3313 				}
3314 				tbin->low_water = tbin->ncached;
3315 				tbin->high_water = tbin->ncached;
3316 			}
3317 		}
3318 
3319 		tcache->next_gc_bin++;
3320 		if (tcache->next_gc_bin == nbins)
3321 			tcache->next_gc_bin = 0;
3322 		tcache->ev_cnt = 0;
3323 	}
3324 }
3325 
3326 static inline void *
tcache_bin_alloc(tcache_bin_t * tbin)3327 tcache_bin_alloc(tcache_bin_t *tbin)
3328 {
3329 
3330 	if (tbin->ncached == 0)
3331 		return (NULL);
3332 	tbin->ncached--;
3333 	if (tbin->ncached < tbin->low_water)
3334 		tbin->low_water = tbin->ncached;
3335 	return (tbin->slots[tbin->ncached]);
3336 }
3337 
3338 static void
tcache_bin_fill(tcache_t * tcache,tcache_bin_t * tbin,size_t binind)3339 tcache_bin_fill(tcache_t *tcache, tcache_bin_t *tbin, size_t binind)
3340 {
3341 	arena_t *arena;
3342 	arena_bin_t *bin;
3343 	arena_run_t *run;
3344 	void *ptr;
3345 	unsigned i;
3346 
3347 	assert(tbin->ncached == 0);
3348 
3349 	arena = tcache->arena;
3350 	bin = &arena->bins[binind];
3351 	malloc_spin_lock(&arena->lock);
3352 	for (i = 0; i < (tcache_nslots >> 1); i++) {
3353 		if ((run = bin->runcur) != NULL && run->nfree > 0)
3354 			ptr = arena_bin_malloc_easy(arena, bin, run);
3355 		else
3356 			ptr = arena_bin_malloc_hard(arena, bin);
3357 		if (ptr == NULL)
3358 			break;
3359 		/*
3360 		 * Fill tbin such that the objects lowest in memory are used
3361 		 * first.
3362 		 */
3363 		tbin->slots[(tcache_nslots >> 1) - 1 - i] = ptr;
3364 	}
3365 #ifdef MALLOC_STATS
3366 	bin->stats.nfills++;
3367 	bin->stats.nrequests += tbin->tstats.nrequests;
3368 	if (bin->reg_size <= small_maxclass) {
3369 		arena->stats.nmalloc_small += (i - tbin->ncached);
3370 		arena->stats.allocated_small += (i - tbin->ncached) *
3371 		    bin->reg_size;
3372 		arena->stats.nmalloc_small += tbin->tstats.nrequests;
3373 	} else {
3374 		arena->stats.nmalloc_medium += (i - tbin->ncached);
3375 		arena->stats.allocated_medium += (i - tbin->ncached) *
3376 		    bin->reg_size;
3377 		arena->stats.nmalloc_medium += tbin->tstats.nrequests;
3378 	}
3379 	tbin->tstats.nrequests = 0;
3380 #endif
3381 	malloc_spin_unlock(&arena->lock);
3382 	tbin->ncached = i;
3383 	if (tbin->ncached > tbin->high_water)
3384 		tbin->high_water = tbin->ncached;
3385 }
3386 
3387 static inline void *
tcache_alloc(tcache_t * tcache,size_t size,bool zero)3388 tcache_alloc(tcache_t *tcache, size_t size, bool zero)
3389 {
3390 	void *ret;
3391 	tcache_bin_t *tbin;
3392 	size_t binind;
3393 
3394 	if (size <= small_maxclass)
3395 		binind = small_size2bin[size];
3396 	else {
3397 		binind = mbin0 + ((MEDIUM_CEILING(size) - medium_min) >>
3398 		    lg_mspace);
3399 	}
3400 	assert(binind < nbins);
3401 	tbin = tcache->tbins[binind];
3402 	if (tbin == NULL) {
3403 		tbin = tcache_bin_create(tcache->arena);
3404 		if (tbin == NULL)
3405 			return (NULL);
3406 		tcache->tbins[binind] = tbin;
3407 	}
3408 
3409 	ret = tcache_bin_alloc(tbin);
3410 	if (ret == NULL) {
3411 		ret = tcache_alloc_hard(tcache, tbin, binind);
3412 		if (ret == NULL)
3413 			return (NULL);
3414 	}
3415 
3416 	if (zero == false) {
3417 		if (opt_junk)
3418 			memset(ret, 0xa5, size);
3419 		else if (opt_zero)
3420 			memset(ret, 0, size);
3421 	} else
3422 		memset(ret, 0, size);
3423 
3424 #ifdef MALLOC_STATS
3425 	tbin->tstats.nrequests++;
3426 #endif
3427 	tcache_event(tcache);
3428 	return (ret);
3429 }
3430 
3431 static void *
tcache_alloc_hard(tcache_t * tcache,tcache_bin_t * tbin,size_t binind)3432 tcache_alloc_hard(tcache_t *tcache, tcache_bin_t *tbin, size_t binind)
3433 {
3434 	void *ret;
3435 
3436 	tcache_bin_fill(tcache, tbin, binind);
3437 	ret = tcache_bin_alloc(tbin);
3438 
3439 	return (ret);
3440 }
3441 #endif
3442 
3443 static inline void *
arena_malloc_small(arena_t * arena,size_t size,bool zero)3444 arena_malloc_small(arena_t *arena, size_t size, bool zero)
3445 {
3446 	void *ret;
3447 	arena_bin_t *bin;
3448 	arena_run_t *run;
3449 	size_t binind;
3450 
3451 	binind = small_size2bin[size];
3452 	assert(binind < mbin0);
3453 	bin = &arena->bins[binind];
3454 	size = bin->reg_size;
3455 
3456 	malloc_spin_lock(&arena->lock);
3457 	if ((run = bin->runcur) != NULL && run->nfree > 0)
3458 		ret = arena_bin_malloc_easy(arena, bin, run);
3459 	else
3460 		ret = arena_bin_malloc_hard(arena, bin);
3461 
3462 	if (ret == NULL) {
3463 		malloc_spin_unlock(&arena->lock);
3464 		return (NULL);
3465 	}
3466 
3467 #ifdef MALLOC_STATS
3468 #  ifdef MALLOC_TCACHE
3469 	if (__isthreaded == false) {
3470 #  endif
3471 		bin->stats.nrequests++;
3472 		arena->stats.nmalloc_small++;
3473 #  ifdef MALLOC_TCACHE
3474 	}
3475 #  endif
3476 	arena->stats.allocated_small += size;
3477 #endif
3478 	malloc_spin_unlock(&arena->lock);
3479 
3480 	if (zero == false) {
3481 		if (opt_junk)
3482 			memset(ret, 0xa5, size);
3483 		else if (opt_zero)
3484 			memset(ret, 0, size);
3485 	} else
3486 		memset(ret, 0, size);
3487 
3488 	return (ret);
3489 }
3490 
3491 static void *
arena_malloc_medium(arena_t * arena,size_t size,bool zero)3492 arena_malloc_medium(arena_t *arena, size_t size, bool zero)
3493 {
3494 	void *ret;
3495 	arena_bin_t *bin;
3496 	arena_run_t *run;
3497 	size_t binind;
3498 
3499 	size = MEDIUM_CEILING(size);
3500 	binind = mbin0 + ((size - medium_min) >> lg_mspace);
3501 	assert(binind < nbins);
3502 	bin = &arena->bins[binind];
3503 	assert(bin->reg_size == size);
3504 
3505 	malloc_spin_lock(&arena->lock);
3506 	if ((run = bin->runcur) != NULL && run->nfree > 0)
3507 		ret = arena_bin_malloc_easy(arena, bin, run);
3508 	else
3509 		ret = arena_bin_malloc_hard(arena, bin);
3510 
3511 	if (ret == NULL) {
3512 		malloc_spin_unlock(&arena->lock);
3513 		return (NULL);
3514 	}
3515 
3516 #ifdef MALLOC_STATS
3517 #  ifdef MALLOC_TCACHE
3518 	if (__isthreaded == false) {
3519 #  endif
3520 		bin->stats.nrequests++;
3521 		arena->stats.nmalloc_medium++;
3522 #  ifdef MALLOC_TCACHE
3523 	}
3524 #  endif
3525 	arena->stats.allocated_medium += size;
3526 #endif
3527 	malloc_spin_unlock(&arena->lock);
3528 
3529 	if (zero == false) {
3530 		if (opt_junk)
3531 			memset(ret, 0xa5, size);
3532 		else if (opt_zero)
3533 			memset(ret, 0, size);
3534 	} else
3535 		memset(ret, 0, size);
3536 
3537 	return (ret);
3538 }
3539 
3540 static void *
arena_malloc_large(arena_t * arena,size_t size,bool zero)3541 arena_malloc_large(arena_t *arena, size_t size, bool zero)
3542 {
3543 	void *ret;
3544 
3545 	/* Large allocation. */
3546 	size = PAGE_CEILING(size);
3547 	malloc_spin_lock(&arena->lock);
3548 	ret = (void *)arena_run_alloc(arena, size, true, zero);
3549 	if (ret == NULL) {
3550 		malloc_spin_unlock(&arena->lock);
3551 		return (NULL);
3552 	}
3553 #ifdef MALLOC_STATS
3554 	arena->stats.nmalloc_large++;
3555 	arena->stats.allocated_large += size;
3556 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].nrequests++;
3557 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns++;
3558 	if (arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns >
3559 	    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns) {
3560 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns =
3561 		    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns;
3562 	}
3563 #endif
3564 	malloc_spin_unlock(&arena->lock);
3565 
3566 	if (zero == false) {
3567 		if (opt_junk)
3568 			memset(ret, 0xa5, size);
3569 		else if (opt_zero)
3570 			memset(ret, 0, size);
3571 	}
3572 
3573 	return (ret);
3574 }
3575 
3576 static inline void *
arena_malloc(size_t size,bool zero)3577 arena_malloc(size_t size, bool zero)
3578 {
3579 
3580 	assert(size != 0);
3581 	assert(QUANTUM_CEILING(size) <= arena_maxclass);
3582 
3583 	if (size <= bin_maxclass) {
3584 #ifdef MALLOC_TCACHE
3585 		if (__isthreaded && tcache_nslots) {
3586 			tcache_t *tcache = tcache_tls;
3587 			if ((uintptr_t)tcache > (uintptr_t)1)
3588 				return (tcache_alloc(tcache, size, zero));
3589 			else if (tcache == NULL) {
3590 				tcache = tcache_create(choose_arena());
3591 				if (tcache == NULL)
3592 					return (NULL);
3593 				return (tcache_alloc(tcache, size, zero));
3594 			}
3595 		}
3596 #endif
3597 		if (size <= small_maxclass) {
3598 			return (arena_malloc_small(choose_arena(), size,
3599 			    zero));
3600 		} else {
3601 			return (arena_malloc_medium(choose_arena(),
3602 			    size, zero));
3603 		}
3604 	} else
3605 		return (arena_malloc_large(choose_arena(), size, zero));
3606 }
3607 
3608 static inline void *
imalloc(size_t size)3609 imalloc(size_t size)
3610 {
3611 
3612 	assert(size != 0);
3613 
3614 	if (size <= arena_maxclass)
3615 		return (arena_malloc(size, false));
3616 	else
3617 		return (huge_malloc(size, false));
3618 }
3619 
3620 static inline void *
icalloc(size_t size)3621 icalloc(size_t size)
3622 {
3623 
3624 	if (size <= arena_maxclass)
3625 		return (arena_malloc(size, true));
3626 	else
3627 		return (huge_malloc(size, true));
3628 }
3629 
3630 /* Only handles large allocations that require more than page alignment. */
3631 static void *
arena_palloc(arena_t * arena,size_t alignment,size_t size,size_t alloc_size)3632 arena_palloc(arena_t *arena, size_t alignment, size_t size, size_t alloc_size)
3633 {
3634 	void *ret;
3635 	size_t offset;
3636 	arena_chunk_t *chunk;
3637 
3638 	assert((size & PAGE_MASK) == 0);
3639 	assert((alignment & PAGE_MASK) == 0);
3640 
3641 	malloc_spin_lock(&arena->lock);
3642 	ret = (void *)arena_run_alloc(arena, alloc_size, true, false);
3643 	if (ret == NULL) {
3644 		malloc_spin_unlock(&arena->lock);
3645 		return (NULL);
3646 	}
3647 
3648 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
3649 
3650 	offset = (uintptr_t)ret & (alignment - 1);
3651 	assert((offset & PAGE_MASK) == 0);
3652 	assert(offset < alloc_size);
3653 	if (offset == 0)
3654 		arena_run_trim_tail(arena, chunk, ret, alloc_size, size, false);
3655 	else {
3656 		size_t leadsize, trailsize;
3657 
3658 		leadsize = alignment - offset;
3659 		if (leadsize > 0) {
3660 			arena_run_trim_head(arena, chunk, ret, alloc_size,
3661 			    alloc_size - leadsize);
3662 			ret = (void *)((uintptr_t)ret + leadsize);
3663 		}
3664 
3665 		trailsize = alloc_size - leadsize - size;
3666 		if (trailsize != 0) {
3667 			/* Trim trailing space. */
3668 			assert(trailsize < alloc_size);
3669 			arena_run_trim_tail(arena, chunk, ret, size + trailsize,
3670 			    size, false);
3671 		}
3672 	}
3673 
3674 #ifdef MALLOC_STATS
3675 	arena->stats.nmalloc_large++;
3676 	arena->stats.allocated_large += size;
3677 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].nrequests++;
3678 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns++;
3679 	if (arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns >
3680 	    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns) {
3681 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns =
3682 		    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns;
3683 	}
3684 #endif
3685 	malloc_spin_unlock(&arena->lock);
3686 
3687 	if (opt_junk)
3688 		memset(ret, 0xa5, size);
3689 	else if (opt_zero)
3690 		memset(ret, 0, size);
3691 	return (ret);
3692 }
3693 
3694 static inline void *
ipalloc(size_t alignment,size_t size)3695 ipalloc(size_t alignment, size_t size)
3696 {
3697 	void *ret;
3698 	size_t ceil_size;
3699 
3700 	/*
3701 	 * Round size up to the nearest multiple of alignment.
3702 	 *
3703 	 * This done, we can take advantage of the fact that for each small
3704 	 * size class, every object is aligned at the smallest power of two
3705 	 * that is non-zero in the base two representation of the size.  For
3706 	 * example:
3707 	 *
3708 	 *   Size |   Base 2 | Minimum alignment
3709 	 *   -----+----------+------------------
3710 	 *     96 |  1100000 |  32
3711 	 *    144 | 10100000 |  32
3712 	 *    192 | 11000000 |  64
3713 	 *
3714 	 * Depending on runtime settings, it is possible that arena_malloc()
3715 	 * will further round up to a power of two, but that never causes
3716 	 * correctness issues.
3717 	 */
3718 	ceil_size = (size + (alignment - 1)) & (-alignment);
3719 	/*
3720 	 * (ceil_size < size) protects against the combination of maximal
3721 	 * alignment and size greater than maximal alignment.
3722 	 */
3723 	if (ceil_size < size) {
3724 		/* size_t overflow. */
3725 		return (NULL);
3726 	}
3727 
3728 	if (ceil_size <= PAGE_SIZE || (alignment <= PAGE_SIZE
3729 	    && ceil_size <= arena_maxclass))
3730 		ret = arena_malloc(ceil_size, false);
3731 	else {
3732 		size_t run_size;
3733 
3734 		/*
3735 		 * We can't achieve subpage alignment, so round up alignment
3736 		 * permanently; it makes later calculations simpler.
3737 		 */
3738 		alignment = PAGE_CEILING(alignment);
3739 		ceil_size = PAGE_CEILING(size);
3740 		/*
3741 		 * (ceil_size < size) protects against very large sizes within
3742 		 * PAGE_SIZE of SIZE_T_MAX.
3743 		 *
3744 		 * (ceil_size + alignment < ceil_size) protects against the
3745 		 * combination of maximal alignment and ceil_size large enough
3746 		 * to cause overflow.  This is similar to the first overflow
3747 		 * check above, but it needs to be repeated due to the new
3748 		 * ceil_size value, which may now be *equal* to maximal
3749 		 * alignment, whereas before we only detected overflow if the
3750 		 * original size was *greater* than maximal alignment.
3751 		 */
3752 		if (ceil_size < size || ceil_size + alignment < ceil_size) {
3753 			/* size_t overflow. */
3754 			return (NULL);
3755 		}
3756 
3757 		/*
3758 		 * Calculate the size of the over-size run that arena_palloc()
3759 		 * would need to allocate in order to guarantee the alignment.
3760 		 */
3761 		if (ceil_size >= alignment)
3762 			run_size = ceil_size + alignment - PAGE_SIZE;
3763 		else {
3764 			/*
3765 			 * It is possible that (alignment << 1) will cause
3766 			 * overflow, but it doesn't matter because we also
3767 			 * subtract PAGE_SIZE, which in the case of overflow
3768 			 * leaves us with a very large run_size.  That causes
3769 			 * the first conditional below to fail, which means
3770 			 * that the bogus run_size value never gets used for
3771 			 * anything important.
3772 			 */
3773 			run_size = (alignment << 1) - PAGE_SIZE;
3774 		}
3775 
3776 		if (run_size <= arena_maxclass) {
3777 			ret = arena_palloc(choose_arena(), alignment, ceil_size,
3778 			    run_size);
3779 		} else if (alignment <= chunksize)
3780 			ret = huge_malloc(ceil_size, false);
3781 		else
3782 			ret = huge_palloc(alignment, ceil_size);
3783 	}
3784 
3785 	assert(((uintptr_t)ret & (alignment - 1)) == 0);
3786 	return (ret);
3787 }
3788 
3789 static bool
arena_is_large(const void * ptr)3790 arena_is_large(const void *ptr)
3791 {
3792 	arena_chunk_t *chunk;
3793 	size_t pageind, mapbits;
3794 
3795 	assert(ptr != NULL);
3796 	assert(CHUNK_ADDR2BASE(ptr) != ptr);
3797 
3798 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3799 	pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT);
3800 	mapbits = chunk->map[pageind].bits;
3801 	assert((mapbits & CHUNK_MAP_ALLOCATED) != 0);
3802 	return ((mapbits & CHUNK_MAP_LARGE) != 0);
3803 }
3804 
3805 /* Return the size of the allocation pointed to by ptr. */
3806 static size_t
arena_salloc(const void * ptr)3807 arena_salloc(const void *ptr)
3808 {
3809 	size_t ret;
3810 	arena_chunk_t *chunk;
3811 	size_t pageind, mapbits;
3812 
3813 	assert(ptr != NULL);
3814 	assert(CHUNK_ADDR2BASE(ptr) != ptr);
3815 
3816 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3817 	pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT);
3818 	mapbits = chunk->map[pageind].bits;
3819 	assert((mapbits & CHUNK_MAP_ALLOCATED) != 0);
3820 	if ((mapbits & CHUNK_MAP_LARGE) == 0) {
3821 		arena_run_t *run = (arena_run_t *)((uintptr_t)chunk +
3822 		    (uintptr_t)((pageind - ((mapbits & CHUNK_MAP_PG_MASK) >>
3823 		    CHUNK_MAP_PG_SHIFT)) << PAGE_SHIFT));
3824 		assert(run->magic == ARENA_RUN_MAGIC);
3825 		ret = run->bin->reg_size;
3826 	} else {
3827 		ret = mapbits & ~PAGE_MASK;
3828 		assert(ret != 0);
3829 	}
3830 
3831 	return (ret);
3832 }
3833 
3834 static inline size_t
isalloc(const void * ptr)3835 isalloc(const void *ptr)
3836 {
3837 	size_t ret;
3838 	arena_chunk_t *chunk;
3839 
3840 	assert(ptr != NULL);
3841 
3842 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3843 	if (chunk != ptr) {
3844 		/* Region. */
3845 		assert(chunk->arena->magic == ARENA_MAGIC);
3846 
3847 		ret = arena_salloc(ptr);
3848 	} else {
3849 		extent_node_t *node, key;
3850 
3851 		/* Chunk (huge allocation). */
3852 
3853 		malloc_mutex_lock(&huge_mtx);
3854 
3855 		/* Extract from tree of huge allocations. */
3856 		key.addr = __DECONST(void *, ptr);
3857 		node = extent_tree_ad_search(&huge, &key);
3858 		assert(node != NULL);
3859 
3860 		ret = node->size;
3861 
3862 		malloc_mutex_unlock(&huge_mtx);
3863 	}
3864 
3865 	return (ret);
3866 }
3867 
3868 static inline void
arena_dalloc_bin(arena_t * arena,arena_chunk_t * chunk,void * ptr,arena_chunk_map_t * mapelm)3869 arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,
3870     arena_chunk_map_t *mapelm)
3871 {
3872 	size_t pageind;
3873 	arena_run_t *run;
3874 	arena_bin_t *bin;
3875 	size_t size;
3876 
3877 	pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT);
3878 	run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
3879 	    ((mapelm->bits & CHUNK_MAP_PG_MASK) >> CHUNK_MAP_PG_SHIFT)) <<
3880 	    PAGE_SHIFT));
3881 	assert(run->magic == ARENA_RUN_MAGIC);
3882 	bin = run->bin;
3883 	size = bin->reg_size;
3884 
3885 	if (opt_junk)
3886 		memset(ptr, 0x5a, size);
3887 
3888 	arena_run_reg_dalloc(run, bin, ptr, size);
3889 	run->nfree++;
3890 
3891 	if (run->nfree == bin->nregs)
3892 		arena_dalloc_bin_run(arena, chunk, run, bin);
3893 	else if (run->nfree == 1 && run != bin->runcur) {
3894 		/*
3895 		 * Make sure that bin->runcur always refers to the lowest
3896 		 * non-full run, if one exists.
3897 		 */
3898 		if (bin->runcur == NULL)
3899 			bin->runcur = run;
3900 		else if ((uintptr_t)run < (uintptr_t)bin->runcur) {
3901 			/* Switch runcur. */
3902 			if (bin->runcur->nfree > 0) {
3903 				arena_chunk_t *runcur_chunk =
3904 				    CHUNK_ADDR2BASE(bin->runcur);
3905 				size_t runcur_pageind =
3906 				    (((uintptr_t)bin->runcur -
3907 				    (uintptr_t)runcur_chunk)) >> PAGE_SHIFT;
3908 				arena_chunk_map_t *runcur_mapelm =
3909 				    &runcur_chunk->map[runcur_pageind];
3910 
3911 				/* Insert runcur. */
3912 				arena_run_tree_insert(&bin->runs,
3913 				    runcur_mapelm);
3914 			}
3915 			bin->runcur = run;
3916 		} else {
3917 			size_t run_pageind = (((uintptr_t)run -
3918 			    (uintptr_t)chunk)) >> PAGE_SHIFT;
3919 			arena_chunk_map_t *run_mapelm =
3920 			    &chunk->map[run_pageind];
3921 
3922 			assert(arena_run_tree_search(&bin->runs, run_mapelm) ==
3923 			    NULL);
3924 			arena_run_tree_insert(&bin->runs, run_mapelm);
3925 		}
3926 	}
3927 
3928 #ifdef MALLOC_STATS
3929 	if (size <= small_maxclass) {
3930 		arena->stats.allocated_small -= size;
3931 		arena->stats.ndalloc_small++;
3932 	} else {
3933 		arena->stats.allocated_medium -= size;
3934 		arena->stats.ndalloc_medium++;
3935 	}
3936 #endif
3937 }
3938 
3939 static void
arena_dalloc_bin_run(arena_t * arena,arena_chunk_t * chunk,arena_run_t * run,arena_bin_t * bin)3940 arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
3941     arena_bin_t *bin)
3942 {
3943 	size_t run_ind;
3944 
3945 	/* Deallocate run. */
3946 	if (run == bin->runcur)
3947 		bin->runcur = NULL;
3948 	else if (bin->nregs != 1) {
3949 		size_t run_pageind = (((uintptr_t)run -
3950 		    (uintptr_t)chunk)) >> PAGE_SHIFT;
3951 		arena_chunk_map_t *run_mapelm =
3952 		    &chunk->map[run_pageind];
3953 		/*
3954 		 * This block's conditional is necessary because if the
3955 		 * run only contains one region, then it never gets
3956 		 * inserted into the non-full runs tree.
3957 		 */
3958 		arena_run_tree_remove(&bin->runs, run_mapelm);
3959 	}
3960 	/*
3961 	 * Mark the first page as dirty.  The dirty bit for every other page in
3962 	 * the run is already properly set, which means we can call
3963 	 * arena_run_dalloc(..., false), thus potentially avoiding the needless
3964 	 * creation of many dirty pages.
3965 	 */
3966 	run_ind = (size_t)(((uintptr_t)run - (uintptr_t)chunk) >> PAGE_SHIFT);
3967 	assert((chunk->map[run_ind].bits & CHUNK_MAP_DIRTY) == 0);
3968 	chunk->map[run_ind].bits |= CHUNK_MAP_DIRTY;
3969 	chunk->ndirty++;
3970 	arena->ndirty++;
3971 
3972 #ifdef MALLOC_DEBUG
3973 	run->magic = 0;
3974 #endif
3975 	arena_run_dalloc(arena, run, false);
3976 #ifdef MALLOC_STATS
3977 	bin->stats.curruns--;
3978 #endif
3979 
3980 	if (chunk->dirtied == false) {
3981 		arena_chunk_tree_dirty_insert(&arena->chunks_dirty, chunk);
3982 		chunk->dirtied = true;
3983 	}
3984 	/* Enforce opt_lg_dirty_mult. */
3985 	if (opt_lg_dirty_mult >= 0 && (arena->nactive >> opt_lg_dirty_mult) <
3986 	    arena->ndirty)
3987 		arena_purge(arena);
3988 }
3989 
3990 #ifdef MALLOC_STATS
3991 static void
arena_stats_print(arena_t * arena)3992 arena_stats_print(arena_t *arena)
3993 {
3994 
3995 	malloc_printf("dirty pages: %zu:%zu active:dirty, %"PRIu64" sweep%s,"
3996 	    " %"PRIu64" madvise%s, %"PRIu64" purged\n",
3997 	    arena->nactive, arena->ndirty,
3998 	    arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
3999 	    arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
4000 	    arena->stats.purged);
4001 
4002 	malloc_printf("            allocated      nmalloc      ndalloc\n");
4003 	malloc_printf("small:   %12zu %12"PRIu64" %12"PRIu64"\n",
4004 	    arena->stats.allocated_small, arena->stats.nmalloc_small,
4005 	    arena->stats.ndalloc_small);
4006 	malloc_printf("medium:  %12zu %12"PRIu64" %12"PRIu64"\n",
4007 	    arena->stats.allocated_medium, arena->stats.nmalloc_medium,
4008 	    arena->stats.ndalloc_medium);
4009 	malloc_printf("large:   %12zu %12"PRIu64" %12"PRIu64"\n",
4010 	    arena->stats.allocated_large, arena->stats.nmalloc_large,
4011 	    arena->stats.ndalloc_large);
4012 	malloc_printf("total:   %12zu %12"PRIu64" %12"PRIu64"\n",
4013 	    arena->stats.allocated_small + arena->stats.allocated_medium +
4014 	    arena->stats.allocated_large, arena->stats.nmalloc_small +
4015 	    arena->stats.nmalloc_medium + arena->stats.nmalloc_large,
4016 	    arena->stats.ndalloc_small + arena->stats.ndalloc_medium +
4017 	    arena->stats.ndalloc_large);
4018 	malloc_printf("mapped:  %12zu\n", arena->stats.mapped);
4019 
4020 	if (arena->stats.nmalloc_small + arena->stats.nmalloc_medium > 0) {
4021 		unsigned i, gap_start;
4022 #ifdef MALLOC_TCACHE
4023 		malloc_printf("bins:     bin    size regs pgs  requests    "
4024 		    "nfills  nflushes   newruns    reruns maxruns curruns\n");
4025 #else
4026 		malloc_printf("bins:     bin    size regs pgs  requests   "
4027 		    "newruns    reruns maxruns curruns\n");
4028 #endif
4029 		for (i = 0, gap_start = UINT_MAX; i < nbins; i++) {
4030 			if (arena->bins[i].stats.nruns == 0) {
4031 				if (gap_start == UINT_MAX)
4032 					gap_start = i;
4033 			} else {
4034 				if (gap_start != UINT_MAX) {
4035 					if (i > gap_start + 1) {
4036 						/*
4037 						 * Gap of more than one size
4038 						 * class.
4039 						 */
4040 						malloc_printf("[%u..%u]\n",
4041 						    gap_start, i - 1);
4042 					} else {
4043 						/* Gap of one size class. */
4044 						malloc_printf("[%u]\n",
4045 						    gap_start);
4046 					}
4047 					gap_start = UINT_MAX;
4048 				}
4049 				malloc_printf(
4050 				    "%13u %1s %5u %4u %3u %9"PRIu64" %9"PRIu64
4051 #ifdef MALLOC_TCACHE
4052 				    " %9"PRIu64" %9"PRIu64
4053 #endif
4054 				    " %9"PRIu64" %7zu %7zu\n",
4055 				    i,
4056 				    i < ntbins ? "T" : i < ntbins + nqbins ?
4057 				    "Q" : i < ntbins + nqbins + ncbins ? "C" :
4058 				    i < ntbins + nqbins + ncbins + nsbins ? "S"
4059 				    : "M",
4060 				    arena->bins[i].reg_size,
4061 				    arena->bins[i].nregs,
4062 				    arena->bins[i].run_size >> PAGE_SHIFT,
4063 				    arena->bins[i].stats.nrequests,
4064 #ifdef MALLOC_TCACHE
4065 				    arena->bins[i].stats.nfills,
4066 				    arena->bins[i].stats.nflushes,
4067 #endif
4068 				    arena->bins[i].stats.nruns,
4069 				    arena->bins[i].stats.reruns,
4070 				    arena->bins[i].stats.highruns,
4071 				    arena->bins[i].stats.curruns);
4072 			}
4073 		}
4074 		if (gap_start != UINT_MAX) {
4075 			if (i > gap_start + 1) {
4076 				/* Gap of more than one size class. */
4077 				malloc_printf("[%u..%u]\n", gap_start, i - 1);
4078 			} else {
4079 				/* Gap of one size class. */
4080 				malloc_printf("[%u]\n", gap_start);
4081 			}
4082 		}
4083 	}
4084 
4085 	if (arena->stats.nmalloc_large > 0) {
4086 		size_t i;
4087 		ssize_t gap_start;
4088 		size_t nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT;
4089 
4090 		malloc_printf(
4091 		    "large:   size pages nrequests   maxruns   curruns\n");
4092 
4093 		for (i = 0, gap_start = -1; i < nlclasses; i++) {
4094 			if (arena->stats.lstats[i].nrequests == 0) {
4095 				if (gap_start == -1)
4096 					gap_start = i;
4097 			} else {
4098 				if (gap_start != -1) {
4099 					malloc_printf("[%zu]\n", i - gap_start);
4100 					gap_start = -1;
4101 				}
4102 				malloc_printf(
4103 				    "%13zu %5zu %9"PRIu64" %9zu %9zu\n",
4104 				    (i+1) << PAGE_SHIFT, i+1,
4105 				    arena->stats.lstats[i].nrequests,
4106 				    arena->stats.lstats[i].highruns,
4107 				    arena->stats.lstats[i].curruns);
4108 			}
4109 		}
4110 		if (gap_start != -1)
4111 			malloc_printf("[%zu]\n", i - gap_start);
4112 	}
4113 }
4114 #endif
4115 
4116 static void
stats_print_atexit(void)4117 stats_print_atexit(void)
4118 {
4119 
4120 #if (defined(MALLOC_TCACHE) && defined(MALLOC_STATS))
4121 	unsigned i;
4122 
4123 	/*
4124 	 * Merge stats from extant threads.  This is racy, since individual
4125 	 * threads do not lock when recording tcache stats events.  As a
4126 	 * consequence, the final stats may be slightly out of date by the time
4127 	 * they are reported, if other threads continue to allocate.
4128 	 */
4129 	for (i = 0; i < narenas; i++) {
4130 		arena_t *arena = arenas[i];
4131 		if (arena != NULL) {
4132 			tcache_t *tcache;
4133 
4134 			malloc_spin_lock(&arena->lock);
4135 			ql_foreach(tcache, &arena->tcache_ql, link) {
4136 				tcache_stats_merge(tcache, arena);
4137 			}
4138 			malloc_spin_unlock(&arena->lock);
4139 		}
4140 	}
4141 #endif
4142 	malloc_stats_print();
4143 }
4144 
4145 #ifdef MALLOC_TCACHE
4146 static void
tcache_bin_flush(tcache_bin_t * tbin,size_t binind,unsigned rem)4147 tcache_bin_flush(tcache_bin_t *tbin, size_t binind, unsigned rem)
4148 {
4149 	arena_chunk_t *chunk;
4150 	arena_t *arena;
4151 	void *ptr;
4152 	unsigned i, ndeferred, ncached;
4153 
4154 	for (ndeferred = tbin->ncached - rem; ndeferred > 0;) {
4155 		ncached = ndeferred;
4156 		/* Lock the arena associated with the first object. */
4157 		chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(tbin->slots[0]);
4158 		arena = chunk->arena;
4159 		malloc_spin_lock(&arena->lock);
4160 		/* Deallocate every object that belongs to the locked arena. */
4161 		for (i = ndeferred = 0; i < ncached; i++) {
4162 			ptr = tbin->slots[i];
4163 			chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
4164 			if (chunk->arena == arena) {
4165 				size_t pageind = (((uintptr_t)ptr -
4166 				    (uintptr_t)chunk) >> PAGE_SHIFT);
4167 				arena_chunk_map_t *mapelm =
4168 				    &chunk->map[pageind];
4169 				arena_dalloc_bin(arena, chunk, ptr, mapelm);
4170 			} else {
4171 				/*
4172 				 * This object was allocated via a different
4173 				 * arena than the one that is currently locked.
4174 				 * Stash the object, so that it can be handled
4175 				 * in a future pass.
4176 				 */
4177 				tbin->slots[ndeferred] = ptr;
4178 				ndeferred++;
4179 			}
4180 		}
4181 #ifdef MALLOC_STATS
4182 		arena->bins[binind].stats.nflushes++;
4183 		{
4184 			arena_bin_t *bin = &arena->bins[binind];
4185 			bin->stats.nrequests += tbin->tstats.nrequests;
4186 			if (bin->reg_size <= small_maxclass) {
4187 				arena->stats.nmalloc_small +=
4188 				    tbin->tstats.nrequests;
4189 			} else {
4190 				arena->stats.nmalloc_medium +=
4191 				    tbin->tstats.nrequests;
4192 			}
4193 			tbin->tstats.nrequests = 0;
4194 		}
4195 #endif
4196 		malloc_spin_unlock(&arena->lock);
4197 	}
4198 
4199 	if (rem > 0) {
4200 		/*
4201 		 * Shift the remaining valid pointers to the base of the slots
4202 		 * array.
4203 		 */
4204 		memmove(&tbin->slots[0], &tbin->slots[tbin->ncached - rem],
4205 		    rem * sizeof(void *));
4206 	}
4207 	tbin->ncached = rem;
4208 }
4209 
4210 static inline void
tcache_dalloc(tcache_t * tcache,void * ptr)4211 tcache_dalloc(tcache_t *tcache, void *ptr)
4212 {
4213 	arena_t *arena;
4214 	arena_chunk_t *chunk;
4215 	arena_run_t *run;
4216 	arena_bin_t *bin;
4217 	tcache_bin_t *tbin;
4218 	size_t pageind, binind;
4219 	arena_chunk_map_t *mapelm;
4220 
4221 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
4222 	arena = chunk->arena;
4223 	pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT);
4224 	mapelm = &chunk->map[pageind];
4225 	run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
4226 	    ((mapelm->bits & CHUNK_MAP_PG_MASK) >> CHUNK_MAP_PG_SHIFT)) <<
4227 	    PAGE_SHIFT));
4228 	assert(run->magic == ARENA_RUN_MAGIC);
4229 	bin = run->bin;
4230 	binind = ((uintptr_t)bin - (uintptr_t)&arena->bins) /
4231 	    sizeof(arena_bin_t);
4232 	assert(binind < nbins);
4233 
4234 	if (opt_junk)
4235 		memset(ptr, 0x5a, arena->bins[binind].reg_size);
4236 
4237 	tbin = tcache->tbins[binind];
4238 	if (tbin == NULL) {
4239 		tbin = tcache_bin_create(choose_arena());
4240 		if (tbin == NULL) {
4241 			malloc_spin_lock(&arena->lock);
4242 			arena_dalloc_bin(arena, chunk, ptr, mapelm);
4243 			malloc_spin_unlock(&arena->lock);
4244 			return;
4245 		}
4246 		tcache->tbins[binind] = tbin;
4247 	}
4248 
4249 	if (tbin->ncached == tcache_nslots)
4250 		tcache_bin_flush(tbin, binind, (tcache_nslots >> 1));
4251 	assert(tbin->ncached < tcache_nslots);
4252 	tbin->slots[tbin->ncached] = ptr;
4253 	tbin->ncached++;
4254 	if (tbin->ncached > tbin->high_water)
4255 		tbin->high_water = tbin->ncached;
4256 
4257 	tcache_event(tcache);
4258 }
4259 #endif
4260 
4261 static void
arena_dalloc_large(arena_t * arena,arena_chunk_t * chunk,void * ptr)4262 arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr)
4263 {
4264 
4265 	/* Large allocation. */
4266 	malloc_spin_lock(&arena->lock);
4267 
4268 #ifndef MALLOC_STATS
4269 	if (opt_junk)
4270 #endif
4271 	{
4272 		size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>
4273 		    PAGE_SHIFT;
4274 		size_t size = chunk->map[pageind].bits & ~PAGE_MASK;
4275 
4276 #ifdef MALLOC_STATS
4277 		if (opt_junk)
4278 #endif
4279 			memset(ptr, 0x5a, size);
4280 #ifdef MALLOC_STATS
4281 		arena->stats.ndalloc_large++;
4282 		arena->stats.allocated_large -= size;
4283 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns--;
4284 #endif
4285 	}
4286 
4287 	arena_run_dalloc(arena, (arena_run_t *)ptr, true);
4288 	malloc_spin_unlock(&arena->lock);
4289 }
4290 
4291 static inline void
arena_dalloc(arena_t * arena,arena_chunk_t * chunk,void * ptr)4292 arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr)
4293 {
4294 	size_t pageind;
4295 	arena_chunk_map_t *mapelm;
4296 
4297 	assert(arena != NULL);
4298 	assert(arena->magic == ARENA_MAGIC);
4299 	assert(chunk->arena == arena);
4300 	assert(ptr != NULL);
4301 	assert(CHUNK_ADDR2BASE(ptr) != ptr);
4302 
4303 	pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT);
4304 	mapelm = &chunk->map[pageind];
4305 	assert((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0);
4306 	if ((mapelm->bits & CHUNK_MAP_LARGE) == 0) {
4307 		/* Small allocation. */
4308 #ifdef MALLOC_TCACHE
4309 		if (__isthreaded && tcache_nslots) {
4310 			tcache_t *tcache = tcache_tls;
4311 			if ((uintptr_t)tcache > (uintptr_t)1)
4312 				tcache_dalloc(tcache, ptr);
4313 			else {
4314 				arena_dalloc_hard(arena, chunk, ptr, mapelm,
4315 				    tcache);
4316 			}
4317 		} else {
4318 #endif
4319 			malloc_spin_lock(&arena->lock);
4320 			arena_dalloc_bin(arena, chunk, ptr, mapelm);
4321 			malloc_spin_unlock(&arena->lock);
4322 #ifdef MALLOC_TCACHE
4323 		}
4324 #endif
4325 	} else
4326 		arena_dalloc_large(arena, chunk, ptr);
4327 }
4328 
4329 #ifdef MALLOC_TCACHE
4330 static void
arena_dalloc_hard(arena_t * arena,arena_chunk_t * chunk,void * ptr,arena_chunk_map_t * mapelm,tcache_t * tcache)4331 arena_dalloc_hard(arena_t *arena, arena_chunk_t *chunk, void *ptr,
4332     arena_chunk_map_t *mapelm, tcache_t *tcache)
4333 {
4334 
4335 	if (tcache == NULL) {
4336 		tcache = tcache_create(arena);
4337 		if (tcache == NULL) {
4338 			malloc_spin_lock(&arena->lock);
4339 			arena_dalloc_bin(arena, chunk, ptr, mapelm);
4340 			malloc_spin_unlock(&arena->lock);
4341 		} else
4342 			tcache_dalloc(tcache, ptr);
4343 	} else {
4344 		/* This thread is currently exiting, so directly deallocate. */
4345 		assert(tcache == (void *)(uintptr_t)1);
4346 		malloc_spin_lock(&arena->lock);
4347 		arena_dalloc_bin(arena, chunk, ptr, mapelm);
4348 		malloc_spin_unlock(&arena->lock);
4349 	}
4350 }
4351 #endif
4352 
4353 static inline void
idalloc(void * ptr)4354 idalloc(void *ptr)
4355 {
4356 	arena_chunk_t *chunk;
4357 
4358 	assert(ptr != NULL);
4359 
4360 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
4361 	if (chunk != ptr)
4362 		arena_dalloc(chunk->arena, chunk, ptr);
4363 	else
4364 		huge_dalloc(ptr);
4365 }
4366 
4367 static void
arena_ralloc_large_shrink(arena_t * arena,arena_chunk_t * chunk,void * ptr,size_t size,size_t oldsize)4368 arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
4369     size_t size, size_t oldsize)
4370 {
4371 
4372 	assert(size < oldsize);
4373 
4374 	/*
4375 	 * Shrink the run, and make trailing pages available for other
4376 	 * allocations.
4377 	 */
4378 	malloc_spin_lock(&arena->lock);
4379 	arena_run_trim_tail(arena, chunk, (arena_run_t *)ptr, oldsize, size,
4380 	    true);
4381 #ifdef MALLOC_STATS
4382 	arena->stats.ndalloc_large++;
4383 	arena->stats.allocated_large -= oldsize;
4384 	arena->stats.lstats[(oldsize >> PAGE_SHIFT) - 1].curruns--;
4385 
4386 	arena->stats.nmalloc_large++;
4387 	arena->stats.allocated_large += size;
4388 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].nrequests++;
4389 	arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns++;
4390 	if (arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns >
4391 	    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns) {
4392 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns =
4393 		    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns;
4394 	}
4395 #endif
4396 	malloc_spin_unlock(&arena->lock);
4397 }
4398 
4399 static bool
arena_ralloc_large_grow(arena_t * arena,arena_chunk_t * chunk,void * ptr,size_t size,size_t oldsize)4400 arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
4401     size_t size, size_t oldsize)
4402 {
4403 	size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT;
4404 	size_t npages = oldsize >> PAGE_SHIFT;
4405 
4406 	assert(oldsize == (chunk->map[pageind].bits & ~PAGE_MASK));
4407 
4408 	/* Try to extend the run. */
4409 	assert(size > oldsize);
4410 	malloc_spin_lock(&arena->lock);
4411 	if (pageind + npages < chunk_npages && (chunk->map[pageind+npages].bits
4412 	    & CHUNK_MAP_ALLOCATED) == 0 && (chunk->map[pageind+npages].bits &
4413 	    ~PAGE_MASK) >= size - oldsize) {
4414 		/*
4415 		 * The next run is available and sufficiently large.  Split the
4416 		 * following run, then merge the first part with the existing
4417 		 * allocation.
4418 		 */
4419 		arena_run_split(arena, (arena_run_t *)((uintptr_t)chunk +
4420 		    ((pageind+npages) << PAGE_SHIFT)), size - oldsize, true,
4421 		    false);
4422 
4423 		chunk->map[pageind].bits = size | CHUNK_MAP_LARGE |
4424 		    CHUNK_MAP_ALLOCATED;
4425 		chunk->map[pageind+npages].bits = CHUNK_MAP_LARGE |
4426 		    CHUNK_MAP_ALLOCATED;
4427 
4428 #ifdef MALLOC_STATS
4429 		arena->stats.ndalloc_large++;
4430 		arena->stats.allocated_large -= oldsize;
4431 		arena->stats.lstats[(oldsize >> PAGE_SHIFT) - 1].curruns--;
4432 
4433 		arena->stats.nmalloc_large++;
4434 		arena->stats.allocated_large += size;
4435 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].nrequests++;
4436 		arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns++;
4437 		if (arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns >
4438 		    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns) {
4439 			arena->stats.lstats[(size >> PAGE_SHIFT) - 1].highruns =
4440 			    arena->stats.lstats[(size >> PAGE_SHIFT) - 1].curruns;
4441 		}
4442 #endif
4443 		malloc_spin_unlock(&arena->lock);
4444 		return (false);
4445 	}
4446 	malloc_spin_unlock(&arena->lock);
4447 
4448 	return (true);
4449 }
4450 
4451 /*
4452  * Try to resize a large allocation, in order to avoid copying.  This will
4453  * always fail if growing an object, and the following run is already in use.
4454  */
4455 static bool
arena_ralloc_large(void * ptr,size_t size,size_t oldsize)4456 arena_ralloc_large(void *ptr, size_t size, size_t oldsize)
4457 {
4458 	size_t psize;
4459 
4460 	psize = PAGE_CEILING(size);
4461 	if (psize == oldsize) {
4462 		/* Same size class. */
4463 		if (opt_junk && size < oldsize) {
4464 			memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize -
4465 			    size);
4466 		}
4467 		return (false);
4468 	} else {
4469 		arena_chunk_t *chunk;
4470 		arena_t *arena;
4471 
4472 		chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
4473 		arena = chunk->arena;
4474 		assert(arena->magic == ARENA_MAGIC);
4475 
4476 		if (psize < oldsize) {
4477 			/* Fill before shrinking in order avoid a race. */
4478 			if (opt_junk) {
4479 				memset((void *)((uintptr_t)ptr + size), 0x5a,
4480 				    oldsize - size);
4481 			}
4482 			arena_ralloc_large_shrink(arena, chunk, ptr, psize,
4483 			    oldsize);
4484 			return (false);
4485 		} else {
4486 			bool ret = arena_ralloc_large_grow(arena, chunk, ptr,
4487 			    psize, oldsize);
4488 			if (ret == false && opt_zero) {
4489 				memset((void *)((uintptr_t)ptr + oldsize), 0,
4490 				    size - oldsize);
4491 			}
4492 			return (ret);
4493 		}
4494 	}
4495 }
4496 
4497 static void *
arena_ralloc(void * ptr,size_t size,size_t oldsize)4498 arena_ralloc(void *ptr, size_t size, size_t oldsize)
4499 {
4500 	void *ret;
4501 	size_t copysize;
4502 
4503 	/*
4504 	 * Try to avoid moving the allocation.
4505 	 *
4506 	 * posix_memalign() can cause allocation of "large" objects that are
4507 	 * smaller than bin_maxclass (in order to meet alignment requirements).
4508 	 * Therefore, do not assume that (oldsize <= bin_maxclass) indicates
4509 	 * ptr refers to a bin-allocated object.
4510 	 */
4511 	if (oldsize <= arena_maxclass) {
4512 		if (arena_is_large(ptr) == false ) {
4513 			if (size <= small_maxclass) {
4514 				if (oldsize <= small_maxclass &&
4515 				    small_size2bin[size] ==
4516 				    small_size2bin[oldsize])
4517 					goto IN_PLACE;
4518 			} else if (size <= bin_maxclass) {
4519 				if (small_maxclass < oldsize && oldsize <=
4520 				    bin_maxclass && MEDIUM_CEILING(size) ==
4521 				    MEDIUM_CEILING(oldsize))
4522 					goto IN_PLACE;
4523 			}
4524 		} else {
4525 			assert(size <= arena_maxclass);
4526 			if (size > bin_maxclass) {
4527 				if (arena_ralloc_large(ptr, size, oldsize) ==
4528 				    false)
4529 					return (ptr);
4530 			}
4531 		}
4532 	}
4533 
4534 	/* Try to avoid moving the allocation. */
4535 	if (size <= small_maxclass) {
4536 		if (oldsize <= small_maxclass && small_size2bin[size] ==
4537 		    small_size2bin[oldsize])
4538 			goto IN_PLACE;
4539 	} else if (size <= bin_maxclass) {
4540 		if (small_maxclass < oldsize && oldsize <= bin_maxclass &&
4541 		    MEDIUM_CEILING(size) == MEDIUM_CEILING(oldsize))
4542 			goto IN_PLACE;
4543 	} else {
4544 		if (bin_maxclass < oldsize && oldsize <= arena_maxclass) {
4545 			assert(size > bin_maxclass);
4546 			if (arena_ralloc_large(ptr, size, oldsize) == false)
4547 				return (ptr);
4548 		}
4549 	}
4550 
4551 	/*
4552 	 * If we get here, then size and oldsize are different enough that we
4553 	 * need to move the object.  In that case, fall back to allocating new
4554 	 * space and copying.
4555 	 */
4556 	ret = arena_malloc(size, false);
4557 	if (ret == NULL)
4558 		return (NULL);
4559 
4560 	/* Junk/zero-filling were already done by arena_malloc(). */
4561 	copysize = (size < oldsize) ? size : oldsize;
4562 	memcpy(ret, ptr, copysize);
4563 	idalloc(ptr);
4564 	return (ret);
4565 IN_PLACE:
4566 	if (opt_junk && size < oldsize)
4567 		memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize - size);
4568 	else if (opt_zero && size > oldsize)
4569 		memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
4570 	return (ptr);
4571 }
4572 
4573 static inline void *
iralloc(void * ptr,size_t size)4574 iralloc(void *ptr, size_t size)
4575 {
4576 	size_t oldsize;
4577 
4578 	assert(ptr != NULL);
4579 	assert(size != 0);
4580 
4581 	oldsize = isalloc(ptr);
4582 
4583 	if (size <= arena_maxclass)
4584 		return (arena_ralloc(ptr, size, oldsize));
4585 	else
4586 		return (huge_ralloc(ptr, size, oldsize));
4587 }
4588 
4589 static bool
arena_new(arena_t * arena,unsigned ind)4590 arena_new(arena_t *arena, unsigned ind)
4591 {
4592 	unsigned i;
4593 	arena_bin_t *bin;
4594 	size_t prev_run_size;
4595 
4596 	if (malloc_spin_init(&arena->lock))
4597 		return (true);
4598 
4599 #ifdef MALLOC_STATS
4600 	memset(&arena->stats, 0, sizeof(arena_stats_t));
4601 	arena->stats.lstats = (malloc_large_stats_t *)base_alloc(
4602 	    sizeof(malloc_large_stats_t) * ((chunksize - PAGE_SIZE) >>
4603 	        PAGE_SHIFT));
4604 	if (arena->stats.lstats == NULL)
4605 		return (true);
4606 	memset(arena->stats.lstats, 0, sizeof(malloc_large_stats_t) *
4607 	    ((chunksize - PAGE_SIZE) >> PAGE_SHIFT));
4608 #  ifdef MALLOC_TCACHE
4609 	ql_new(&arena->tcache_ql);
4610 #  endif
4611 #endif
4612 
4613 	/* Initialize chunks. */
4614 	arena_chunk_tree_dirty_new(&arena->chunks_dirty);
4615 	arena->spare = NULL;
4616 
4617 	arena->nactive = 0;
4618 	arena->ndirty = 0;
4619 
4620 	arena_avail_tree_new(&arena->runs_avail);
4621 
4622 	/* Initialize bins. */
4623 	prev_run_size = PAGE_SIZE;
4624 
4625 	i = 0;
4626 #ifdef MALLOC_TINY
4627 	/* (2^n)-spaced tiny bins. */
4628 	for (; i < ntbins; i++) {
4629 		bin = &arena->bins[i];
4630 		bin->runcur = NULL;
4631 		arena_run_tree_new(&bin->runs);
4632 
4633 		bin->reg_size = (1U << (LG_TINY_MIN + i));
4634 
4635 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
4636 
4637 #ifdef MALLOC_STATS
4638 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
4639 #endif
4640 	}
4641 #endif
4642 
4643 	/* Quantum-spaced bins. */
4644 	for (; i < ntbins + nqbins; i++) {
4645 		bin = &arena->bins[i];
4646 		bin->runcur = NULL;
4647 		arena_run_tree_new(&bin->runs);
4648 
4649 		bin->reg_size = (i - ntbins + 1) << LG_QUANTUM;
4650 
4651 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
4652 
4653 #ifdef MALLOC_STATS
4654 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
4655 #endif
4656 	}
4657 
4658 	/* Cacheline-spaced bins. */
4659 	for (; i < ntbins + nqbins + ncbins; i++) {
4660 		bin = &arena->bins[i];
4661 		bin->runcur = NULL;
4662 		arena_run_tree_new(&bin->runs);
4663 
4664 		bin->reg_size = cspace_min + ((i - (ntbins + nqbins)) <<
4665 		    LG_CACHELINE);
4666 
4667 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
4668 
4669 #ifdef MALLOC_STATS
4670 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
4671 #endif
4672 	}
4673 
4674 	/* Subpage-spaced bins. */
4675 	for (; i < ntbins + nqbins + ncbins + nsbins; i++) {
4676 		bin = &arena->bins[i];
4677 		bin->runcur = NULL;
4678 		arena_run_tree_new(&bin->runs);
4679 
4680 		bin->reg_size = sspace_min + ((i - (ntbins + nqbins + ncbins))
4681 		    << LG_SUBPAGE);
4682 
4683 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
4684 
4685 #ifdef MALLOC_STATS
4686 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
4687 #endif
4688 	}
4689 
4690 	/* Medium bins. */
4691 	for (; i < nbins; i++) {
4692 		bin = &arena->bins[i];
4693 		bin->runcur = NULL;
4694 		arena_run_tree_new(&bin->runs);
4695 
4696 		bin->reg_size = medium_min + ((i - (ntbins + nqbins + ncbins +
4697 		    nsbins)) << lg_mspace);
4698 
4699 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
4700 
4701 #ifdef MALLOC_STATS
4702 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
4703 #endif
4704 	}
4705 
4706 #ifdef MALLOC_DEBUG
4707 	arena->magic = ARENA_MAGIC;
4708 #endif
4709 
4710 	return (false);
4711 }
4712 
4713 /* Create a new arena and insert it into the arenas array at index ind. */
4714 static arena_t *
arenas_extend(unsigned ind)4715 arenas_extend(unsigned ind)
4716 {
4717 	arena_t *ret;
4718 
4719 	/* Allocate enough space for trailing bins. */
4720 	ret = (arena_t *)base_alloc(sizeof(arena_t)
4721 	    + (sizeof(arena_bin_t) * (nbins - 1)));
4722 	if (ret != NULL && arena_new(ret, ind) == false) {
4723 		arenas[ind] = ret;
4724 		return (ret);
4725 	}
4726 	/* Only reached if there is an OOM error. */
4727 
4728 	/*
4729 	 * OOM here is quite inconvenient to propagate, since dealing with it
4730 	 * would require a check for failure in the fast path.  Instead, punt
4731 	 * by using arenas[0].  In practice, this is an extremely unlikely
4732 	 * failure.
4733 	 */
4734 	_malloc_message(_getprogname(),
4735 	    ": (malloc) Error initializing arena\n", "", "");
4736 	if (opt_abort)
4737 		abort();
4738 
4739 	return (arenas[0]);
4740 }
4741 
4742 #ifdef MALLOC_TCACHE
4743 static tcache_bin_t *
tcache_bin_create(arena_t * arena)4744 tcache_bin_create(arena_t *arena)
4745 {
4746 	tcache_bin_t *ret;
4747 	size_t tsize;
4748 
4749 	tsize = sizeof(tcache_bin_t) + (sizeof(void *) * (tcache_nslots - 1));
4750 	if (tsize <= small_maxclass)
4751 		ret = (tcache_bin_t *)arena_malloc_small(arena, tsize, false);
4752 	else if (tsize <= bin_maxclass)
4753 		ret = (tcache_bin_t *)arena_malloc_medium(arena, tsize, false);
4754 	else
4755 		ret = (tcache_bin_t *)imalloc(tsize);
4756 	if (ret == NULL)
4757 		return (NULL);
4758 #ifdef MALLOC_STATS
4759 	memset(&ret->tstats, 0, sizeof(tcache_bin_stats_t));
4760 #endif
4761 	ret->low_water = 0;
4762 	ret->high_water = 0;
4763 	ret->ncached = 0;
4764 
4765 	return (ret);
4766 }
4767 
4768 static void
tcache_bin_destroy(tcache_t * tcache,tcache_bin_t * tbin,unsigned binind)4769 tcache_bin_destroy(tcache_t *tcache, tcache_bin_t *tbin, unsigned binind)
4770 {
4771 	arena_t *arena;
4772 	arena_chunk_t *chunk;
4773 	size_t pageind, tsize;
4774 	arena_chunk_map_t *mapelm;
4775 
4776 	chunk = CHUNK_ADDR2BASE(tbin);
4777 	arena = chunk->arena;
4778 	pageind = (((uintptr_t)tbin - (uintptr_t)chunk) >> PAGE_SHIFT);
4779 	mapelm = &chunk->map[pageind];
4780 
4781 #ifdef MALLOC_STATS
4782 	if (tbin->tstats.nrequests != 0) {
4783 		arena_t *arena = tcache->arena;
4784 		arena_bin_t *bin = &arena->bins[binind];
4785 		malloc_spin_lock(&arena->lock);
4786 		bin->stats.nrequests += tbin->tstats.nrequests;
4787 		if (bin->reg_size <= small_maxclass)
4788 			arena->stats.nmalloc_small += tbin->tstats.nrequests;
4789 		else
4790 			arena->stats.nmalloc_medium += tbin->tstats.nrequests;
4791 		malloc_spin_unlock(&arena->lock);
4792 	}
4793 #endif
4794 
4795 	assert(tbin->ncached == 0);
4796 	tsize = sizeof(tcache_bin_t) + (sizeof(void *) * (tcache_nslots - 1));
4797 	if (tsize <= bin_maxclass) {
4798 		malloc_spin_lock(&arena->lock);
4799 		arena_dalloc_bin(arena, chunk, tbin, mapelm);
4800 		malloc_spin_unlock(&arena->lock);
4801 	} else
4802 		idalloc(tbin);
4803 }
4804 
4805 #ifdef MALLOC_STATS
4806 static void
tcache_stats_merge(tcache_t * tcache,arena_t * arena)4807 tcache_stats_merge(tcache_t *tcache, arena_t *arena)
4808 {
4809 	unsigned i;
4810 
4811 	/* Merge and reset tcache stats. */
4812 	for (i = 0; i < mbin0; i++) {
4813 		arena_bin_t *bin = &arena->bins[i];
4814 		tcache_bin_t *tbin = tcache->tbins[i];
4815 		if (tbin != NULL) {
4816 			bin->stats.nrequests += tbin->tstats.nrequests;
4817 			arena->stats.nmalloc_small += tbin->tstats.nrequests;
4818 			tbin->tstats.nrequests = 0;
4819 		}
4820 	}
4821 	for (; i < nbins; i++) {
4822 		arena_bin_t *bin = &arena->bins[i];
4823 		tcache_bin_t *tbin = tcache->tbins[i];
4824 		if (tbin != NULL) {
4825 			bin->stats.nrequests += tbin->tstats.nrequests;
4826 			arena->stats.nmalloc_medium += tbin->tstats.nrequests;
4827 			tbin->tstats.nrequests = 0;
4828 		}
4829 	}
4830 }
4831 #endif
4832 
4833 static tcache_t *
tcache_create(arena_t * arena)4834 tcache_create(arena_t *arena)
4835 {
4836 	tcache_t *tcache;
4837 
4838 	if (sizeof(tcache_t) + (sizeof(tcache_bin_t *) * (nbins - 1)) <=
4839 	    small_maxclass) {
4840 		tcache = (tcache_t *)arena_malloc_small(arena, sizeof(tcache_t)
4841 		    + (sizeof(tcache_bin_t *) * (nbins - 1)), true);
4842 	} else if (sizeof(tcache_t) + (sizeof(tcache_bin_t *) * (nbins - 1)) <=
4843 	    bin_maxclass) {
4844 		tcache = (tcache_t *)arena_malloc_medium(arena, sizeof(tcache_t)
4845 		    + (sizeof(tcache_bin_t *) * (nbins - 1)), true);
4846 	} else {
4847 		tcache = (tcache_t *)icalloc(sizeof(tcache_t) +
4848 		    (sizeof(tcache_bin_t *) * (nbins - 1)));
4849 	}
4850 
4851 	if (tcache == NULL)
4852 		return (NULL);
4853 
4854 #ifdef MALLOC_STATS
4855 	/* Link into list of extant tcaches. */
4856 	malloc_spin_lock(&arena->lock);
4857 	ql_elm_new(tcache, link);
4858 	ql_tail_insert(&arena->tcache_ql, tcache, link);
4859 	malloc_spin_unlock(&arena->lock);
4860 #endif
4861 
4862 	tcache->arena = arena;
4863 
4864 	tcache_tls = tcache;
4865 
4866 	return (tcache);
4867 }
4868 
4869 static void
tcache_destroy(tcache_t * tcache)4870 tcache_destroy(tcache_t *tcache)
4871 {
4872 	unsigned i;
4873 
4874 #ifdef MALLOC_STATS
4875 	/* Unlink from list of extant tcaches. */
4876 	malloc_spin_lock(&tcache->arena->lock);
4877 	ql_remove(&tcache->arena->tcache_ql, tcache, link);
4878 	tcache_stats_merge(tcache, tcache->arena);
4879 	malloc_spin_unlock(&tcache->arena->lock);
4880 #endif
4881 
4882 	for (i = 0; i < nbins; i++) {
4883 		tcache_bin_t *tbin = tcache->tbins[i];
4884 		if (tbin != NULL) {
4885 			tcache_bin_flush(tbin, i, 0);
4886 			tcache_bin_destroy(tcache, tbin, i);
4887 		}
4888 	}
4889 
4890 	if (arena_salloc(tcache) <= bin_maxclass) {
4891 		arena_chunk_t *chunk = CHUNK_ADDR2BASE(tcache);
4892 		arena_t *arena = chunk->arena;
4893 		size_t pageind = (((uintptr_t)tcache - (uintptr_t)chunk) >>
4894 		    PAGE_SHIFT);
4895 		arena_chunk_map_t *mapelm = &chunk->map[pageind];
4896 
4897 		malloc_spin_lock(&arena->lock);
4898 		arena_dalloc_bin(arena, chunk, tcache, mapelm);
4899 		malloc_spin_unlock(&arena->lock);
4900 	} else
4901 		idalloc(tcache);
4902 }
4903 #endif
4904 
4905 /*
4906  * End arena.
4907  */
4908 /******************************************************************************/
4909 /*
4910  * Begin general internal functions.
4911  */
4912 
4913 static void *
huge_malloc(size_t size,bool zero)4914 huge_malloc(size_t size, bool zero)
4915 {
4916 	void *ret;
4917 	size_t csize;
4918 	extent_node_t *node;
4919 
4920 	/* Allocate one or more contiguous chunks for this request. */
4921 
4922 	csize = CHUNK_CEILING(size);
4923 	if (csize == 0) {
4924 		/* size is large enough to cause size_t wrap-around. */
4925 		return (NULL);
4926 	}
4927 
4928 	/* Allocate an extent node with which to track the chunk. */
4929 	node = base_node_alloc();
4930 	if (node == NULL)
4931 		return (NULL);
4932 
4933 	ret = chunk_alloc(csize, &zero);
4934 	if (ret == NULL) {
4935 		base_node_dealloc(node);
4936 		return (NULL);
4937 	}
4938 
4939 	/* Insert node into huge. */
4940 	node->addr = ret;
4941 	node->size = csize;
4942 
4943 	malloc_mutex_lock(&huge_mtx);
4944 	extent_tree_ad_insert(&huge, node);
4945 #ifdef MALLOC_STATS
4946 	huge_nmalloc++;
4947 	huge_allocated += csize;
4948 #endif
4949 	malloc_mutex_unlock(&huge_mtx);
4950 
4951 	if (zero == false) {
4952 		if (opt_junk)
4953 			memset(ret, 0xa5, csize);
4954 		else if (opt_zero)
4955 			memset(ret, 0, csize);
4956 	}
4957 
4958 	return (ret);
4959 }
4960 
4961 /* Only handles large allocations that require more than chunk alignment. */
4962 static void *
huge_palloc(size_t alignment,size_t size)4963 huge_palloc(size_t alignment, size_t size)
4964 {
4965 	void *ret;
4966 	size_t alloc_size, chunk_size, offset;
4967 	extent_node_t *node;
4968 	bool zero;
4969 
4970 	/*
4971 	 * This allocation requires alignment that is even larger than chunk
4972 	 * alignment.  This means that huge_malloc() isn't good enough.
4973 	 *
4974 	 * Allocate almost twice as many chunks as are demanded by the size or
4975 	 * alignment, in order to assure the alignment can be achieved, then
4976 	 * unmap leading and trailing chunks.
4977 	 */
4978 	assert(alignment >= chunksize);
4979 
4980 	chunk_size = CHUNK_CEILING(size);
4981 
4982 	if (size >= alignment)
4983 		alloc_size = chunk_size + alignment - chunksize;
4984 	else
4985 		alloc_size = (alignment << 1) - chunksize;
4986 
4987 	/* Allocate an extent node with which to track the chunk. */
4988 	node = base_node_alloc();
4989 	if (node == NULL)
4990 		return (NULL);
4991 
4992 	zero = false;
4993 	ret = chunk_alloc(alloc_size, &zero);
4994 	if (ret == NULL) {
4995 		base_node_dealloc(node);
4996 		return (NULL);
4997 	}
4998 
4999 	offset = (uintptr_t)ret & (alignment - 1);
5000 	assert((offset & chunksize_mask) == 0);
5001 	assert(offset < alloc_size);
5002 	if (offset == 0) {
5003 		/* Trim trailing space. */
5004 		chunk_dealloc((void *)((uintptr_t)ret + chunk_size), alloc_size
5005 		    - chunk_size);
5006 	} else {
5007 		size_t trailsize;
5008 
5009 		/* Trim leading space. */
5010 		chunk_dealloc(ret, alignment - offset);
5011 
5012 		ret = (void *)((uintptr_t)ret + (alignment - offset));
5013 
5014 		trailsize = alloc_size - (alignment - offset) - chunk_size;
5015 		if (trailsize != 0) {
5016 		    /* Trim trailing space. */
5017 		    assert(trailsize < alloc_size);
5018 		    chunk_dealloc((void *)((uintptr_t)ret + chunk_size),
5019 			trailsize);
5020 		}
5021 	}
5022 
5023 	/* Insert node into huge. */
5024 	node->addr = ret;
5025 	node->size = chunk_size;
5026 
5027 	malloc_mutex_lock(&huge_mtx);
5028 	extent_tree_ad_insert(&huge, node);
5029 #ifdef MALLOC_STATS
5030 	huge_nmalloc++;
5031 	huge_allocated += chunk_size;
5032 #endif
5033 	malloc_mutex_unlock(&huge_mtx);
5034 
5035 	if (opt_junk)
5036 		memset(ret, 0xa5, chunk_size);
5037 	else if (opt_zero)
5038 		memset(ret, 0, chunk_size);
5039 
5040 	return (ret);
5041 }
5042 
5043 static void *
huge_ralloc(void * ptr,size_t size,size_t oldsize)5044 huge_ralloc(void *ptr, size_t size, size_t oldsize)
5045 {
5046 	void *ret;
5047 	size_t copysize;
5048 
5049 	/* Avoid moving the allocation if the size class would not change. */
5050 	if (oldsize > arena_maxclass &&
5051 	    CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
5052 		if (opt_junk && size < oldsize) {
5053 			memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize
5054 			    - size);
5055 		} else if (opt_zero && size > oldsize) {
5056 			memset((void *)((uintptr_t)ptr + oldsize), 0, size
5057 			    - oldsize);
5058 		}
5059 		return (ptr);
5060 	}
5061 
5062 	/*
5063 	 * If we get here, then size and oldsize are different enough that we
5064 	 * need to use a different size class.  In that case, fall back to
5065 	 * allocating new space and copying.
5066 	 */
5067 	ret = huge_malloc(size, false);
5068 	if (ret == NULL)
5069 		return (NULL);
5070 
5071 	copysize = (size < oldsize) ? size : oldsize;
5072 	memcpy(ret, ptr, copysize);
5073 	idalloc(ptr);
5074 	return (ret);
5075 }
5076 
5077 static void
huge_dalloc(void * ptr)5078 huge_dalloc(void *ptr)
5079 {
5080 	extent_node_t *node, key;
5081 
5082 	malloc_mutex_lock(&huge_mtx);
5083 
5084 	/* Extract from tree of huge allocations. */
5085 	key.addr = ptr;
5086 	node = extent_tree_ad_search(&huge, &key);
5087 	assert(node != NULL);
5088 	assert(node->addr == ptr);
5089 	extent_tree_ad_remove(&huge, node);
5090 
5091 #ifdef MALLOC_STATS
5092 	huge_ndalloc++;
5093 	huge_allocated -= node->size;
5094 #endif
5095 
5096 	malloc_mutex_unlock(&huge_mtx);
5097 
5098 	/* Unmap chunk. */
5099 #ifdef MALLOC_DSS
5100 	if (opt_dss && opt_junk)
5101 		memset(node->addr, 0x5a, node->size);
5102 #endif
5103 	chunk_dealloc(node->addr, node->size);
5104 
5105 	base_node_dealloc(node);
5106 }
5107 
5108 static void
malloc_stats_print(void)5109 malloc_stats_print(void)
5110 {
5111 	char s[UMAX2S_BUFSIZE];
5112 
5113 	_malloc_message("___ Begin malloc statistics ___\n", "", "", "");
5114 	_malloc_message("Assertions ",
5115 #ifdef NDEBUG
5116 	    "disabled",
5117 #else
5118 	    "enabled",
5119 #endif
5120 	    "\n", "");
5121 	_malloc_message("Boolean MALLOC_OPTIONS: ", opt_abort ? "A" : "a", "", "");
5122 #ifdef MALLOC_DSS
5123 	_malloc_message(opt_dss ? "D" : "d", "", "", "");
5124 #endif
5125 	_malloc_message(opt_junk ? "J" : "j", "", "", "");
5126 #ifdef MALLOC_DSS
5127 	_malloc_message(opt_mmap ? "M" : "m", "", "", "");
5128 #endif
5129 	_malloc_message("P", "", "", "");
5130 	_malloc_message(opt_utrace ? "U" : "u", "", "", "");
5131 	_malloc_message(opt_sysv ? "V" : "v", "", "", "");
5132 	_malloc_message(opt_xmalloc ? "X" : "x", "", "", "");
5133 	_malloc_message(opt_zero ? "Z" : "z", "", "", "");
5134 	_malloc_message("\n", "", "", "");
5135 
5136 	_malloc_message("CPUs: ", umax2s(ncpus, 10, s), "\n", "");
5137 	_malloc_message("Max arenas: ", umax2s(narenas, 10, s), "\n", "");
5138 	_malloc_message("Pointer size: ", umax2s(sizeof(void *), 10, s), "\n", "");
5139 	_malloc_message("Quantum size: ", umax2s(QUANTUM, 10, s), "\n", "");
5140 	_malloc_message("Cacheline size (assumed): ",
5141 	    umax2s(CACHELINE, 10, s), "\n", "");
5142 	_malloc_message("Subpage spacing: ", umax2s(SUBPAGE, 10, s), "\n", "");
5143 	_malloc_message("Medium spacing: ", umax2s((1U << lg_mspace), 10, s), "\n",
5144 	    "");
5145 #ifdef MALLOC_TINY
5146 	_malloc_message("Tiny 2^n-spaced sizes: [", umax2s((1U << LG_TINY_MIN), 10,
5147 	    s), "..", "");
5148 	_malloc_message(umax2s((qspace_min >> 1), 10, s), "]\n", "", "");
5149 #endif
5150 	_malloc_message("Quantum-spaced sizes: [", umax2s(qspace_min, 10, s), "..",
5151 	    "");
5152 	_malloc_message(umax2s(qspace_max, 10, s), "]\n", "", "");
5153 	_malloc_message("Cacheline-spaced sizes: [",
5154 	    umax2s(cspace_min, 10, s), "..", "");
5155 	_malloc_message(umax2s(cspace_max, 10, s), "]\n", "", "");
5156 	_malloc_message("Subpage-spaced sizes: [", umax2s(sspace_min, 10, s), "..",
5157 	    "");
5158 	_malloc_message(umax2s(sspace_max, 10, s), "]\n", "", "");
5159 	_malloc_message("Medium sizes: [", umax2s(medium_min, 10, s), "..", "");
5160 	_malloc_message(umax2s(medium_max, 10, s), "]\n", "", "");
5161 	if (opt_lg_dirty_mult >= 0) {
5162 		_malloc_message("Min active:dirty page ratio per arena: ",
5163 		    umax2s((1U << opt_lg_dirty_mult), 10, s), ":1\n", "");
5164 	} else {
5165 		_malloc_message("Min active:dirty page ratio per arena: N/A\n", "",
5166 		    "", "");
5167 	}
5168 #ifdef MALLOC_TCACHE
5169 	_malloc_message("Thread cache slots per size class: ",
5170 	    tcache_nslots ? umax2s(tcache_nslots, 10, s) : "N/A", "\n", "");
5171 	_malloc_message("Thread cache GC sweep interval: ",
5172 	    (tcache_nslots && tcache_gc_incr > 0) ?
5173 	    umax2s((1U << opt_lg_tcache_gc_sweep), 10, s) : "N/A", "", "");
5174 	_malloc_message(" (increment interval: ",
5175 	    (tcache_nslots && tcache_gc_incr > 0) ?  umax2s(tcache_gc_incr, 10, s)
5176 	    : "N/A", ")\n", "");
5177 #endif
5178 	_malloc_message("Chunk size: ", umax2s(chunksize, 10, s), "", "");
5179 	_malloc_message(" (2^", umax2s(opt_lg_chunk, 10, s), ")\n", "");
5180 
5181 #ifdef MALLOC_STATS
5182 	{
5183 		size_t allocated, mapped;
5184 		unsigned i;
5185 		arena_t *arena;
5186 
5187 		/* Calculate and print allocated/mapped stats. */
5188 
5189 		/* arenas. */
5190 		for (i = 0, allocated = 0; i < narenas; i++) {
5191 			if (arenas[i] != NULL) {
5192 				malloc_spin_lock(&arenas[i]->lock);
5193 				allocated += arenas[i]->stats.allocated_small;
5194 				allocated += arenas[i]->stats.allocated_large;
5195 				malloc_spin_unlock(&arenas[i]->lock);
5196 			}
5197 		}
5198 
5199 		/* huge/base. */
5200 		malloc_mutex_lock(&huge_mtx);
5201 		allocated += huge_allocated;
5202 		mapped = stats_chunks.curchunks * chunksize;
5203 		malloc_mutex_unlock(&huge_mtx);
5204 
5205 		malloc_mutex_lock(&base_mtx);
5206 		mapped += base_mapped;
5207 		malloc_mutex_unlock(&base_mtx);
5208 
5209 		malloc_printf("Allocated: %zu, mapped: %zu\n", allocated,
5210 		    mapped);
5211 
5212 		/* Print chunk stats. */
5213 		{
5214 			chunk_stats_t chunks_stats;
5215 
5216 			malloc_mutex_lock(&huge_mtx);
5217 			chunks_stats = stats_chunks;
5218 			malloc_mutex_unlock(&huge_mtx);
5219 
5220 			malloc_printf("chunks: nchunks   "
5221 			    "highchunks    curchunks\n");
5222 			malloc_printf("  %13"PRIu64"%13zu%13zu\n",
5223 			    chunks_stats.nchunks, chunks_stats.highchunks,
5224 			    chunks_stats.curchunks);
5225 		}
5226 
5227 		/* Print chunk stats. */
5228 		malloc_printf(
5229 		    "huge: nmalloc      ndalloc    allocated\n");
5230 		malloc_printf(" %12"PRIu64" %12"PRIu64" %12zu\n", huge_nmalloc,
5231 		    huge_ndalloc, huge_allocated);
5232 
5233 		/* Print stats for each arena. */
5234 		for (i = 0; i < narenas; i++) {
5235 			arena = arenas[i];
5236 			if (arena != NULL) {
5237 				malloc_printf("\narenas[%u]:\n", i);
5238 				malloc_spin_lock(&arena->lock);
5239 				arena_stats_print(arena);
5240 				malloc_spin_unlock(&arena->lock);
5241 			}
5242 		}
5243 	}
5244 #endif /* #ifdef MALLOC_STATS */
5245 	_malloc_message("--- End malloc statistics ---\n", "", "", "");
5246 }
5247 
5248 #ifdef MALLOC_DEBUG
5249 static void
small_size2bin_validate(void)5250 small_size2bin_validate(void)
5251 {
5252 	size_t i, size, binind;
5253 
5254 	assert(small_size2bin[0] == 0xffU);
5255 	i = 1;
5256 #  ifdef MALLOC_TINY
5257 	/* Tiny. */
5258 	for (; i < (1U << LG_TINY_MIN); i++) {
5259 		size = pow2_ceil(1U << LG_TINY_MIN);
5260 		binind = ffs((int)(size >> (LG_TINY_MIN + 1)));
5261 		assert(small_size2bin[i] == binind);
5262 	}
5263 	for (; i < qspace_min; i++) {
5264 		size = pow2_ceil(i);
5265 		binind = ffs((int)(size >> (LG_TINY_MIN + 1)));
5266 		assert(small_size2bin[i] == binind);
5267 	}
5268 #  endif
5269 	/* Quantum-spaced. */
5270 	for (; i <= qspace_max; i++) {
5271 		size = QUANTUM_CEILING(i);
5272 		binind = ntbins + (size >> LG_QUANTUM) - 1;
5273 		assert(small_size2bin[i] == binind);
5274 	}
5275 	/* Cacheline-spaced. */
5276 	for (; i <= cspace_max; i++) {
5277 		size = CACHELINE_CEILING(i);
5278 		binind = ntbins + nqbins + ((size - cspace_min) >>
5279 		    LG_CACHELINE);
5280 		assert(small_size2bin[i] == binind);
5281 	}
5282 	/* Sub-page. */
5283 	for (; i <= sspace_max; i++) {
5284 		size = SUBPAGE_CEILING(i);
5285 		binind = ntbins + nqbins + ncbins + ((size - sspace_min)
5286 		    >> LG_SUBPAGE);
5287 		assert(small_size2bin[i] == binind);
5288 	}
5289 }
5290 #endif
5291 
5292 static bool
small_size2bin_init(void)5293 small_size2bin_init(void)
5294 {
5295 
5296 	if (opt_lg_qspace_max != LG_QSPACE_MAX_DEFAULT
5297 	    || opt_lg_cspace_max != LG_CSPACE_MAX_DEFAULT
5298 	    || sizeof(const_small_size2bin) != small_maxclass + 1)
5299 		return (small_size2bin_init_hard());
5300 
5301 	small_size2bin = const_small_size2bin;
5302 #ifdef MALLOC_DEBUG
5303 	assert(sizeof(const_small_size2bin) == small_maxclass + 1);
5304 	small_size2bin_validate();
5305 #endif
5306 	return (false);
5307 }
5308 
5309 static bool
small_size2bin_init_hard(void)5310 small_size2bin_init_hard(void)
5311 {
5312 	size_t i, size, binind;
5313 	uint8_t *custom_small_size2bin;
5314 
5315 	assert(opt_lg_qspace_max != LG_QSPACE_MAX_DEFAULT
5316 	    || opt_lg_cspace_max != LG_CSPACE_MAX_DEFAULT
5317 	    || sizeof(const_small_size2bin) != small_maxclass + 1);
5318 
5319 	custom_small_size2bin = (uint8_t *)base_alloc(small_maxclass + 1);
5320 	if (custom_small_size2bin == NULL)
5321 		return (true);
5322 
5323 	custom_small_size2bin[0] = 0xffU;
5324 	i = 1;
5325 #ifdef MALLOC_TINY
5326 	/* Tiny. */
5327 	for (; i < (1U << LG_TINY_MIN); i++) {
5328 		size = pow2_ceil(1U << LG_TINY_MIN);
5329 		binind = ffs((int)(size >> (LG_TINY_MIN + 1)));
5330 		custom_small_size2bin[i] = binind;
5331 	}
5332 	for (; i < qspace_min; i++) {
5333 		size = pow2_ceil(i);
5334 		binind = ffs((int)(size >> (LG_TINY_MIN + 1)));
5335 		custom_small_size2bin[i] = binind;
5336 	}
5337 #endif
5338 	/* Quantum-spaced. */
5339 	for (; i <= qspace_max; i++) {
5340 		size = QUANTUM_CEILING(i);
5341 		binind = ntbins + (size >> LG_QUANTUM) - 1;
5342 		custom_small_size2bin[i] = binind;
5343 	}
5344 	/* Cacheline-spaced. */
5345 	for (; i <= cspace_max; i++) {
5346 		size = CACHELINE_CEILING(i);
5347 		binind = ntbins + nqbins + ((size - cspace_min) >>
5348 		    LG_CACHELINE);
5349 		custom_small_size2bin[i] = binind;
5350 	}
5351 	/* Sub-page. */
5352 	for (; i <= sspace_max; i++) {
5353 		size = SUBPAGE_CEILING(i);
5354 		binind = ntbins + nqbins + ncbins + ((size - sspace_min) >>
5355 		    LG_SUBPAGE);
5356 		custom_small_size2bin[i] = binind;
5357 	}
5358 
5359 	small_size2bin = custom_small_size2bin;
5360 #ifdef MALLOC_DEBUG
5361 	small_size2bin_validate();
5362 #endif
5363 	return (false);
5364 }
5365 
5366 static unsigned
malloc_ncpus(void)5367 malloc_ncpus(void)
5368 {
5369 	int mib[2];
5370 	unsigned ret;
5371 	int error;
5372 	size_t len;
5373 
5374 	error = _elf_aux_info(AT_NCPUS, &ret, sizeof(ret));
5375 	if (error != 0 || ret == 0) {
5376 		mib[0] = CTL_HW;
5377 		mib[1] = HW_NCPU;
5378 		len = sizeof(ret);
5379 		if (sysctl(mib, 2, &ret, &len, (void *)NULL, 0) == -1) {
5380 			/* Error. */
5381 			ret = 1;
5382 		}
5383 	}
5384 
5385 	return (ret);
5386 }
5387 
5388 /*
5389  * FreeBSD's pthreads implementation calls malloc(3), so the malloc
5390  * implementation has to take pains to avoid infinite recursion during
5391  * initialization.
5392  */
5393 static inline bool
malloc_init(void)5394 malloc_init(void)
5395 {
5396 
5397 	if (malloc_initialized == false)
5398 		return (malloc_init_hard());
5399 
5400 	return (false);
5401 }
5402 
5403 static bool
malloc_init_hard(void)5404 malloc_init_hard(void)
5405 {
5406 	unsigned i;
5407 	int linklen;
5408 	char buf[PATH_MAX + 1];
5409 	const char *opts;
5410 
5411 	malloc_mutex_lock(&init_lock);
5412 	if (malloc_initialized) {
5413 		/*
5414 		 * Another thread initialized the allocator before this one
5415 		 * acquired init_lock.
5416 		 */
5417 		malloc_mutex_unlock(&init_lock);
5418 		return (false);
5419 	}
5420 
5421 	/* Get number of CPUs. */
5422 	ncpus = malloc_ncpus();
5423 
5424 	/*
5425 	 * Increase the chunk size to the largest page size that is greater
5426 	 * than the default chunk size and less than or equal to 4MB.
5427 	 */
5428 	{
5429 		size_t pagesizes[MAXPAGESIZES];
5430 		int k, nsizes;
5431 
5432 		nsizes = getpagesizes(pagesizes, MAXPAGESIZES);
5433 		for (k = 0; k < nsizes; k++)
5434 			if (pagesizes[k] <= (1LU << 22))
5435 				while ((1LU << opt_lg_chunk) < pagesizes[k])
5436 					opt_lg_chunk++;
5437 	}
5438 
5439 	for (i = 0; i < 3; i++) {
5440 		unsigned j;
5441 
5442 		/* Get runtime configuration. */
5443 		switch (i) {
5444 		case 0:
5445 			if ((linklen = readlink("/etc/malloc.conf", buf,
5446 						sizeof(buf) - 1)) != -1) {
5447 				/*
5448 				 * Use the contents of the "/etc/malloc.conf"
5449 				 * symbolic link's name.
5450 				 */
5451 				buf[linklen] = '\0';
5452 				opts = buf;
5453 			} else {
5454 				/* No configuration specified. */
5455 				buf[0] = '\0';
5456 				opts = buf;
5457 			}
5458 			break;
5459 		case 1:
5460 			if (issetugid() == 0 && (opts =
5461 			    getenv("MALLOC_OPTIONS")) != NULL) {
5462 				/*
5463 				 * Do nothing; opts is already initialized to
5464 				 * the value of the MALLOC_OPTIONS environment
5465 				 * variable.
5466 				 */
5467 			} else {
5468 				/* No configuration specified. */
5469 				buf[0] = '\0';
5470 				opts = buf;
5471 			}
5472 			break;
5473 		case 2:
5474 			if (_malloc_options != NULL) {
5475 				/*
5476 				 * Use options that were compiled into the
5477 				 * program.
5478 				 */
5479 				opts = _malloc_options;
5480 			} else {
5481 				/* No configuration specified. */
5482 				buf[0] = '\0';
5483 				opts = buf;
5484 			}
5485 			break;
5486 		default:
5487 			/* NOTREACHED */
5488 			assert(false);
5489 			buf[0] = '\0';
5490 			opts = buf;
5491 		}
5492 
5493 		for (j = 0; opts[j] != '\0'; j++) {
5494 			unsigned k, nreps;
5495 			bool nseen;
5496 
5497 			/* Parse repetition count, if any. */
5498 			for (nreps = 0, nseen = false;; j++, nseen = true) {
5499 				switch (opts[j]) {
5500 					case '0': case '1': case '2': case '3':
5501 					case '4': case '5': case '6': case '7':
5502 					case '8': case '9':
5503 						nreps *= 10;
5504 						nreps += opts[j] - '0';
5505 						break;
5506 					default:
5507 						goto MALLOC_OUT;
5508 				}
5509 			}
5510 MALLOC_OUT:
5511 			if (nseen == false)
5512 				nreps = 1;
5513 
5514 			for (k = 0; k < nreps; k++) {
5515 				switch (opts[j]) {
5516 				case 'a':
5517 					opt_abort = false;
5518 					break;
5519 				case 'A':
5520 					opt_abort = true;
5521 					break;
5522 				case 'c':
5523 					if (opt_lg_cspace_max - 1 >
5524 					    opt_lg_qspace_max &&
5525 					    opt_lg_cspace_max >
5526 					    LG_CACHELINE)
5527 						opt_lg_cspace_max--;
5528 					break;
5529 				case 'C':
5530 					if (opt_lg_cspace_max < PAGE_SHIFT
5531 					    - 1)
5532 						opt_lg_cspace_max++;
5533 					break;
5534 				case 'd':
5535 #ifdef MALLOC_DSS
5536 					opt_dss = false;
5537 #endif
5538 					break;
5539 				case 'D':
5540 #ifdef MALLOC_DSS
5541 					opt_dss = true;
5542 #endif
5543 					break;
5544 				case 'e':
5545 					if (opt_lg_medium_max > PAGE_SHIFT)
5546 						opt_lg_medium_max--;
5547 					break;
5548 				case 'E':
5549 					if (opt_lg_medium_max + 1 <
5550 					    opt_lg_chunk)
5551 						opt_lg_medium_max++;
5552 					break;
5553 				case 'f':
5554 					if (opt_lg_dirty_mult + 1 <
5555 					    (sizeof(size_t) << 3))
5556 						opt_lg_dirty_mult++;
5557 					break;
5558 				case 'F':
5559 					if (opt_lg_dirty_mult >= 0)
5560 						opt_lg_dirty_mult--;
5561 					break;
5562 #ifdef MALLOC_TCACHE
5563 				case 'g':
5564 					if (opt_lg_tcache_gc_sweep >= 0)
5565 						opt_lg_tcache_gc_sweep--;
5566 					break;
5567 				case 'G':
5568 					if (opt_lg_tcache_gc_sweep + 1 <
5569 					    (sizeof(size_t) << 3))
5570 						opt_lg_tcache_gc_sweep++;
5571 					break;
5572 				case 'h':
5573 					if (opt_lg_tcache_nslots > 0)
5574 						opt_lg_tcache_nslots--;
5575 					break;
5576 				case 'H':
5577 					if (opt_lg_tcache_nslots + 1 <
5578 					    (sizeof(size_t) << 3))
5579 						opt_lg_tcache_nslots++;
5580 					break;
5581 #endif
5582 				case 'j':
5583 					opt_junk = false;
5584 					break;
5585 				case 'J':
5586 					opt_junk = true;
5587 					break;
5588 				case 'k':
5589 					/*
5590 					 * Chunks always require at least one
5591 					 * header page, plus enough room to
5592 					 * hold a run for the largest medium
5593 					 * size class (one page more than the
5594 					 * size).
5595 					 */
5596 					if ((1U << (opt_lg_chunk - 1)) >=
5597 					    (2U << PAGE_SHIFT) + (1U <<
5598 					    opt_lg_medium_max))
5599 						opt_lg_chunk--;
5600 					break;
5601 				case 'K':
5602 					if (opt_lg_chunk + 1 <
5603 					    (sizeof(size_t) << 3))
5604 						opt_lg_chunk++;
5605 					break;
5606 				case 'm':
5607 #ifdef MALLOC_DSS
5608 					opt_mmap = false;
5609 #endif
5610 					break;
5611 				case 'M':
5612 #ifdef MALLOC_DSS
5613 					opt_mmap = true;
5614 #endif
5615 					break;
5616 				case 'n':
5617 					opt_narenas_lshift--;
5618 					break;
5619 				case 'N':
5620 					opt_narenas_lshift++;
5621 					break;
5622 				case 'p':
5623 					opt_stats_print = false;
5624 					break;
5625 				case 'P':
5626 					opt_stats_print = true;
5627 					break;
5628 				case 'q':
5629 					if (opt_lg_qspace_max > LG_QUANTUM)
5630 						opt_lg_qspace_max--;
5631 					break;
5632 				case 'Q':
5633 					if (opt_lg_qspace_max + 1 <
5634 					    opt_lg_cspace_max)
5635 						opt_lg_qspace_max++;
5636 					break;
5637 				case 'u':
5638 					opt_utrace = false;
5639 					break;
5640 				case 'U':
5641 					opt_utrace = true;
5642 					break;
5643 				case 'v':
5644 					opt_sysv = false;
5645 					break;
5646 				case 'V':
5647 					opt_sysv = true;
5648 					break;
5649 				case 'x':
5650 					opt_xmalloc = false;
5651 					break;
5652 				case 'X':
5653 					opt_xmalloc = true;
5654 					break;
5655 				case 'z':
5656 					opt_zero = false;
5657 					break;
5658 				case 'Z':
5659 					opt_zero = true;
5660 					break;
5661 				default: {
5662 					char cbuf[2];
5663 
5664 					cbuf[0] = opts[j];
5665 					cbuf[1] = '\0';
5666 					_malloc_message(_getprogname(),
5667 					    ": (malloc) Unsupported character "
5668 					    "in malloc options: '", cbuf,
5669 					    "'\n");
5670 				}
5671 				}
5672 			}
5673 		}
5674 	}
5675 
5676 #ifdef MALLOC_DSS
5677 	/* Make sure that there is some method for acquiring memory. */
5678 	if (opt_dss == false && opt_mmap == false)
5679 		opt_mmap = true;
5680 #endif
5681 	if (opt_stats_print) {
5682 		/* Print statistics at exit. */
5683 		atexit(stats_print_atexit);
5684 	}
5685 
5686 
5687 	/* Set variables according to the value of opt_lg_[qc]space_max. */
5688 	qspace_max = (1U << opt_lg_qspace_max);
5689 	cspace_min = CACHELINE_CEILING(qspace_max);
5690 	if (cspace_min == qspace_max)
5691 		cspace_min += CACHELINE;
5692 	cspace_max = (1U << opt_lg_cspace_max);
5693 	sspace_min = SUBPAGE_CEILING(cspace_max);
5694 	if (sspace_min == cspace_max)
5695 		sspace_min += SUBPAGE;
5696 	assert(sspace_min < PAGE_SIZE);
5697 	sspace_max = PAGE_SIZE - SUBPAGE;
5698 	medium_max = (1U << opt_lg_medium_max);
5699 
5700 #ifdef MALLOC_TINY
5701 	assert(LG_QUANTUM >= LG_TINY_MIN);
5702 #endif
5703 	assert(ntbins <= LG_QUANTUM);
5704 	nqbins = qspace_max >> LG_QUANTUM;
5705 	ncbins = ((cspace_max - cspace_min) >> LG_CACHELINE) + 1;
5706 	nsbins = ((sspace_max - sspace_min) >> LG_SUBPAGE) + 1;
5707 
5708 	/*
5709 	 * Compute medium size class spacing and the number of medium size
5710 	 * classes.  Limit spacing to no more than pagesize, but if possible
5711 	 * use the smallest spacing that does not exceed NMBINS_MAX medium size
5712 	 * classes.
5713 	 */
5714 	lg_mspace = LG_SUBPAGE;
5715 	nmbins = ((medium_max - medium_min) >> lg_mspace) + 1;
5716 	while (lg_mspace < PAGE_SHIFT && nmbins > NMBINS_MAX) {
5717 		lg_mspace = lg_mspace + 1;
5718 		nmbins = ((medium_max - medium_min) >> lg_mspace) + 1;
5719 	}
5720 	mspace_mask = (1U << lg_mspace) - 1U;
5721 
5722 	mbin0 = ntbins + nqbins + ncbins + nsbins;
5723 	nbins = mbin0 + nmbins;
5724 	/*
5725 	 * The small_size2bin lookup table uses uint8_t to encode each bin
5726 	 * index, so we cannot support more than 256 small size classes.  This
5727 	 * limit is difficult to exceed (not even possible with 16B quantum and
5728 	 * 4KiB pages), and such configurations are impractical, but
5729 	 * nonetheless we need to protect against this case in order to avoid
5730 	 * undefined behavior.
5731 	 */
5732 	if (mbin0 > 256) {
5733 	    char line_buf[UMAX2S_BUFSIZE];
5734 	    _malloc_message(_getprogname(),
5735 	        ": (malloc) Too many small size classes (",
5736 	        umax2s(mbin0, 10, line_buf), " > max 256)\n");
5737 	    abort();
5738 	}
5739 
5740 	if (small_size2bin_init()) {
5741 		malloc_mutex_unlock(&init_lock);
5742 		return (true);
5743 	}
5744 
5745 #ifdef MALLOC_TCACHE
5746 	if (opt_lg_tcache_nslots > 0) {
5747 		tcache_nslots = (1U << opt_lg_tcache_nslots);
5748 
5749 		/* Compute incremental GC event threshold. */
5750 		if (opt_lg_tcache_gc_sweep >= 0) {
5751 			tcache_gc_incr = ((1U << opt_lg_tcache_gc_sweep) /
5752 			    nbins) + (((1U << opt_lg_tcache_gc_sweep) % nbins ==
5753 			    0) ? 0 : 1);
5754 		} else
5755 			tcache_gc_incr = 0;
5756 	} else
5757 		tcache_nslots = 0;
5758 #endif
5759 
5760 	/* Set variables according to the value of opt_lg_chunk. */
5761 	chunksize = (1LU << opt_lg_chunk);
5762 	chunksize_mask = chunksize - 1;
5763 	chunk_npages = (chunksize >> PAGE_SHIFT);
5764 	{
5765 		size_t header_size;
5766 
5767 		/*
5768 		 * Compute the header size such that it is large enough to
5769 		 * contain the page map.
5770 		 */
5771 		header_size = sizeof(arena_chunk_t) +
5772 		    (sizeof(arena_chunk_map_t) * (chunk_npages - 1));
5773 		arena_chunk_header_npages = (header_size >> PAGE_SHIFT) +
5774 		    ((header_size & PAGE_MASK) != 0);
5775 	}
5776 	arena_maxclass = chunksize - (arena_chunk_header_npages <<
5777 	    PAGE_SHIFT);
5778 
5779 	UTRACE((void *)(intptr_t)(-1), 0, 0);
5780 
5781 #ifdef MALLOC_STATS
5782 	malloc_mutex_init(&chunks_mtx);
5783 	memset(&stats_chunks, 0, sizeof(chunk_stats_t));
5784 #endif
5785 
5786 	/* Various sanity checks that regard configuration. */
5787 	assert(chunksize >= PAGE_SIZE);
5788 
5789 	/* Initialize chunks data. */
5790 	malloc_mutex_init(&huge_mtx);
5791 	extent_tree_ad_new(&huge);
5792 #ifdef MALLOC_DSS
5793 	malloc_mutex_init(&dss_mtx);
5794 	dss_base = sbrk(0);
5795 	i = (uintptr_t)dss_base & QUANTUM_MASK;
5796 	if (i != 0)
5797 		dss_base = sbrk(QUANTUM - i);
5798 	dss_prev = dss_base;
5799 	dss_max = dss_base;
5800 	extent_tree_szad_new(&dss_chunks_szad);
5801 	extent_tree_ad_new(&dss_chunks_ad);
5802 #endif
5803 #ifdef MALLOC_STATS
5804 	huge_nmalloc = 0;
5805 	huge_ndalloc = 0;
5806 	huge_allocated = 0;
5807 #endif
5808 
5809 	/* Initialize base allocation data structures. */
5810 #ifdef MALLOC_STATS
5811 	base_mapped = 0;
5812 #endif
5813 #ifdef MALLOC_DSS
5814 	/*
5815 	 * Allocate a base chunk here, since it doesn't actually have to be
5816 	 * chunk-aligned.  Doing this before allocating any other chunks allows
5817 	 * the use of space that would otherwise be wasted.
5818 	 */
5819 	if (opt_dss)
5820 		base_pages_alloc(0);
5821 #endif
5822 	base_nodes = NULL;
5823 	malloc_mutex_init(&base_mtx);
5824 
5825 	if (ncpus > 1) {
5826 		/*
5827 		 * For SMP systems, create more than one arena per CPU by
5828 		 * default.
5829 		 */
5830 #ifdef MALLOC_TCACHE
5831 		if (tcache_nslots) {
5832 			/*
5833 			 * Only large object allocation/deallocation is
5834 			 * guaranteed to acquire an arena mutex, so we can get
5835 			 * away with fewer arenas than without thread caching.
5836 			 */
5837 			opt_narenas_lshift += 1;
5838 		} else {
5839 #endif
5840 			/*
5841 			 * All allocations must acquire an arena mutex, so use
5842 			 * plenty of arenas.
5843 			 */
5844 			opt_narenas_lshift += 2;
5845 #ifdef MALLOC_TCACHE
5846 		}
5847 #endif
5848 	}
5849 
5850 	/* Determine how many arenas to use. */
5851 	narenas = ncpus;
5852 	if (opt_narenas_lshift > 0) {
5853 		if ((narenas << opt_narenas_lshift) > narenas)
5854 			narenas <<= opt_narenas_lshift;
5855 		/*
5856 		 * Make sure not to exceed the limits of what base_alloc() can
5857 		 * handle.
5858 		 */
5859 		if (narenas * sizeof(arena_t *) > chunksize)
5860 			narenas = chunksize / sizeof(arena_t *);
5861 	} else if (opt_narenas_lshift < 0) {
5862 		if ((narenas >> -opt_narenas_lshift) < narenas)
5863 			narenas >>= -opt_narenas_lshift;
5864 		/* Make sure there is at least one arena. */
5865 		if (narenas == 0)
5866 			narenas = 1;
5867 	}
5868 
5869 #ifdef NO_TLS
5870 	if (narenas > 1) {
5871 		static const unsigned primes[] = {1, 3, 5, 7, 11, 13, 17, 19,
5872 		    23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
5873 		    89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
5874 		    151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
5875 		    223, 227, 229, 233, 239, 241, 251, 257, 263};
5876 		unsigned nprimes, parenas;
5877 
5878 		/*
5879 		 * Pick a prime number of hash arenas that is more than narenas
5880 		 * so that direct hashing of pthread_self() pointers tends to
5881 		 * spread allocations evenly among the arenas.
5882 		 */
5883 		assert((narenas & 1) == 0); /* narenas must be even. */
5884 		nprimes = (sizeof(primes) >> LG_SIZEOF_INT);
5885 		parenas = primes[nprimes - 1]; /* In case not enough primes. */
5886 		for (i = 1; i < nprimes; i++) {
5887 			if (primes[i] > narenas) {
5888 				parenas = primes[i];
5889 				break;
5890 			}
5891 		}
5892 		narenas = parenas;
5893 	}
5894 #endif
5895 
5896 #ifndef NO_TLS
5897 	next_arena = 0;
5898 #endif
5899 
5900 	/* Allocate and initialize arenas. */
5901 	arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
5902 	if (arenas == NULL) {
5903 		malloc_mutex_unlock(&init_lock);
5904 		return (true);
5905 	}
5906 	/*
5907 	 * Zero the array.  In practice, this should always be pre-zeroed,
5908 	 * since it was just mmap()ed, but let's be sure.
5909 	 */
5910 	memset(arenas, 0, sizeof(arena_t *) * narenas);
5911 
5912 	/*
5913 	 * Initialize one arena here.  The rest are lazily created in
5914 	 * choose_arena_hard().
5915 	 */
5916 	arenas_extend(0);
5917 	if (arenas[0] == NULL) {
5918 		malloc_mutex_unlock(&init_lock);
5919 		return (true);
5920 	}
5921 #ifndef NO_TLS
5922 	/*
5923 	 * Assign the initial arena to the initial thread, in order to avoid
5924 	 * spurious creation of an extra arena if the application switches to
5925 	 * threaded mode.
5926 	 */
5927 	arenas_map = arenas[0];
5928 #endif
5929 	malloc_spin_init(&arenas_lock);
5930 
5931 	malloc_initialized = true;
5932 	malloc_mutex_unlock(&init_lock);
5933 	return (false);
5934 }
5935 
5936 /*
5937  * End general internal functions.
5938  */
5939 /******************************************************************************/
5940 /*
5941  * Begin malloc(3)-compatible functions.
5942  */
5943 
5944 void *
malloc(size_t size)5945 malloc(size_t size)
5946 {
5947 	void *ret;
5948 
5949 	if (malloc_init()) {
5950 		ret = NULL;
5951 		goto OOM;
5952 	}
5953 
5954 	if (size == 0) {
5955 		if (opt_sysv == false)
5956 			size = 1;
5957 		else {
5958 			if (opt_xmalloc) {
5959 				_malloc_message(_getprogname(),
5960 				    ": (malloc) Error in malloc(): "
5961 				    "invalid size 0\n", "", "");
5962 				abort();
5963 			}
5964 			ret = NULL;
5965 			goto RETURN;
5966 		}
5967 	}
5968 
5969 	ret = imalloc(size);
5970 
5971 OOM:
5972 	if (ret == NULL) {
5973 		if (opt_xmalloc) {
5974 			_malloc_message(_getprogname(),
5975 			    ": (malloc) Error in malloc(): out of memory\n", "",
5976 			    "");
5977 			abort();
5978 		}
5979 		errno = ENOMEM;
5980 	}
5981 
5982 RETURN:
5983 	UTRACE(0, size, ret);
5984 	return (ret);
5985 }
5986 
5987 int
posix_memalign(void ** memptr,size_t alignment,size_t size)5988 posix_memalign(void **memptr, size_t alignment, size_t size)
5989 {
5990 	int ret;
5991 	void *result;
5992 
5993 	if (malloc_init())
5994 		result = NULL;
5995 	else {
5996 		if (size == 0) {
5997 			if (opt_sysv == false)
5998 				size = 1;
5999 			else {
6000 				if (opt_xmalloc) {
6001 					_malloc_message(_getprogname(),
6002 					    ": (malloc) Error in "
6003 					    "posix_memalign(): invalid "
6004 					    "size 0\n", "", "");
6005 					abort();
6006 				}
6007 				result = NULL;
6008 				*memptr = NULL;
6009 				ret = 0;
6010 				goto RETURN;
6011 			}
6012 		}
6013 
6014 		/* Make sure that alignment is a large enough power of 2. */
6015 		if (((alignment - 1) & alignment) != 0
6016 		    || alignment < sizeof(void *)) {
6017 			if (opt_xmalloc) {
6018 				_malloc_message(_getprogname(),
6019 				    ": (malloc) Error in posix_memalign(): "
6020 				    "invalid alignment\n", "", "");
6021 				abort();
6022 			}
6023 			result = NULL;
6024 			ret = EINVAL;
6025 			goto RETURN;
6026 		}
6027 
6028 		result = ipalloc(alignment, size);
6029 	}
6030 
6031 	if (result == NULL) {
6032 		if (opt_xmalloc) {
6033 			_malloc_message(_getprogname(),
6034 			": (malloc) Error in posix_memalign(): out of memory\n",
6035 			"", "");
6036 			abort();
6037 		}
6038 		ret = ENOMEM;
6039 		goto RETURN;
6040 	}
6041 
6042 	*memptr = result;
6043 	ret = 0;
6044 
6045 RETURN:
6046 	UTRACE(0, size, result);
6047 	return (ret);
6048 }
6049 
6050 void *
aligned_alloc(size_t alignment,size_t size)6051 aligned_alloc(size_t alignment, size_t size)
6052 {
6053 	void *memptr;
6054 	int ret;
6055 
6056 	ret = posix_memalign(&memptr, alignment, size);
6057 	if (ret != 0) {
6058 		errno = ret;
6059 		return (NULL);
6060 	}
6061 	return (memptr);
6062 }
6063 
6064 void *
calloc(size_t num,size_t size)6065 calloc(size_t num, size_t size)
6066 {
6067 	void *ret;
6068 	size_t num_size;
6069 
6070 	if (malloc_init()) {
6071 		num_size = 0;
6072 		ret = NULL;
6073 		goto RETURN;
6074 	}
6075 
6076 	num_size = num * size;
6077 	if (num_size == 0) {
6078 		if ((opt_sysv == false) && ((num == 0) || (size == 0)))
6079 			num_size = 1;
6080 		else {
6081 			ret = NULL;
6082 			goto RETURN;
6083 		}
6084 	/*
6085 	 * Try to avoid division here.  We know that it isn't possible to
6086 	 * overflow during multiplication if neither operand uses any of the
6087 	 * most significant half of the bits in a size_t.
6088 	 */
6089 	} else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
6090 	    && (num_size / size != num)) {
6091 		/* size_t overflow. */
6092 		ret = NULL;
6093 		goto RETURN;
6094 	}
6095 
6096 	ret = icalloc(num_size);
6097 
6098 RETURN:
6099 	if (ret == NULL) {
6100 		if (opt_xmalloc) {
6101 			_malloc_message(_getprogname(),
6102 			    ": (malloc) Error in calloc(): out of memory\n", "",
6103 			    "");
6104 			abort();
6105 		}
6106 		errno = ENOMEM;
6107 	}
6108 
6109 	UTRACE(0, num_size, ret);
6110 	return (ret);
6111 }
6112 
6113 void *
realloc(void * ptr,size_t size)6114 realloc(void *ptr, size_t size)
6115 {
6116 	void *ret;
6117 
6118 	if (size == 0) {
6119 		if (opt_sysv == false)
6120 			size = 1;
6121 		else {
6122 			if (ptr != NULL)
6123 				idalloc(ptr);
6124 			ret = NULL;
6125 			goto RETURN;
6126 		}
6127 	}
6128 
6129 	if (ptr != NULL) {
6130 		assert(malloc_initialized);
6131 
6132 		ret = iralloc(ptr, size);
6133 
6134 		if (ret == NULL) {
6135 			if (opt_xmalloc) {
6136 				_malloc_message(_getprogname(),
6137 				    ": (malloc) Error in realloc(): out of "
6138 				    "memory\n", "", "");
6139 				abort();
6140 			}
6141 			errno = ENOMEM;
6142 		}
6143 	} else {
6144 		if (malloc_init())
6145 			ret = NULL;
6146 		else
6147 			ret = imalloc(size);
6148 
6149 		if (ret == NULL) {
6150 			if (opt_xmalloc) {
6151 				_malloc_message(_getprogname(),
6152 				    ": (malloc) Error in realloc(): out of "
6153 				    "memory\n", "", "");
6154 				abort();
6155 			}
6156 			errno = ENOMEM;
6157 		}
6158 	}
6159 
6160 RETURN:
6161 	UTRACE(ptr, size, ret);
6162 	return (ret);
6163 }
6164 
6165 void
free(void * ptr)6166 free(void *ptr)
6167 {
6168 
6169 	UTRACE(ptr, 0, 0);
6170 	if (ptr != NULL) {
6171 		assert(malloc_initialized);
6172 
6173 		idalloc(ptr);
6174 	}
6175 }
6176 
6177 /*
6178  * End malloc(3)-compatible functions.
6179  */
6180 /******************************************************************************/
6181 /*
6182  * Begin non-standard functions.
6183  */
6184 
6185 size_t
malloc_usable_size(const void * ptr)6186 malloc_usable_size(const void *ptr)
6187 {
6188 
6189 	assert(ptr != NULL);
6190 
6191 	return (isalloc(ptr));
6192 }
6193 
6194 /*
6195  * End non-standard functions.
6196  */
6197 /******************************************************************************/
6198 /*
6199  * Begin library-private functions.
6200  */
6201 
6202 /*
6203  * We provide an unpublished interface in order to receive notifications from
6204  * the pthreads library whenever a thread exits.  This allows us to clean up
6205  * thread caches.
6206  */
6207 void
_malloc_thread_cleanup(void)6208 _malloc_thread_cleanup(void)
6209 {
6210 
6211 #ifdef MALLOC_TCACHE
6212 	tcache_t *tcache = tcache_tls;
6213 
6214 	if (tcache != NULL) {
6215 		assert(tcache != (void *)(uintptr_t)1);
6216 		tcache_destroy(tcache);
6217 		tcache_tls = (void *)(uintptr_t)1;
6218 	}
6219 #endif
6220 }
6221 
6222 /*
6223  * The following functions are used by threading libraries for protection of
6224  * malloc during fork().  These functions are only called if the program is
6225  * running in threaded mode, so there is no need to check whether the program
6226  * is threaded here.
6227  */
6228 
6229 void
_malloc_prefork(void)6230 _malloc_prefork(void)
6231 {
6232 	unsigned i;
6233 
6234 	/* Acquire all mutexes in a safe order. */
6235 	malloc_spin_lock(&arenas_lock);
6236 	for (i = 0; i < narenas; i++) {
6237 		if (arenas[i] != NULL)
6238 			malloc_spin_lock(&arenas[i]->lock);
6239 	}
6240 
6241 	malloc_mutex_lock(&base_mtx);
6242 
6243 	malloc_mutex_lock(&huge_mtx);
6244 
6245 #ifdef MALLOC_DSS
6246 	malloc_mutex_lock(&dss_mtx);
6247 #endif
6248 }
6249 
6250 void
_malloc_postfork(void)6251 _malloc_postfork(void)
6252 {
6253 	unsigned i;
6254 
6255 	/* Release all mutexes, now that fork() has completed. */
6256 
6257 #ifdef MALLOC_DSS
6258 	malloc_mutex_unlock(&dss_mtx);
6259 #endif
6260 
6261 	malloc_mutex_unlock(&huge_mtx);
6262 
6263 	malloc_mutex_unlock(&base_mtx);
6264 
6265 	for (i = 0; i < narenas; i++) {
6266 		if (arenas[i] != NULL)
6267 			malloc_spin_unlock(&arenas[i]->lock);
6268 	}
6269 	malloc_spin_unlock(&arenas_lock);
6270 }
6271 
6272 /*
6273  * End library-private functions.
6274  */
6275 /******************************************************************************/
6276