annotate jemalloc.c @ 0:9a44d900ee55

initial import
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 05 Oct 2009 16:06:43 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1 /* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2 /* vim:set softtabstop=8 shiftwidth=8: */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3 /*-
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4 * Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5 * All rights reserved.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7 * Redistribution and use in source and binary forms, with or without
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
8 * modification, are permitted provided that the following conditions
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
9 * are met:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
10 * 1. Redistributions of source code must retain the above copyright
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
11 * notice(s), this list of conditions and the following disclaimer as
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
12 * the first lines of this file unmodified other than the possible
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
13 * addition of one or more copyright notices.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
14 * 2. Redistributions in binary form must reproduce the above copyright
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
15 * notice(s), this list of conditions and the following disclaimer in
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
16 * the documentation and/or other materials provided with the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
17 * distribution.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
18 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
30 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
31 *******************************************************************************
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
32 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
33 * This allocator implementation is designed to provide scalable performance
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
34 * for multi-threaded programs on multi-processor systems. The following
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
35 * features are included for this purpose:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
36 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
37 * + Multiple arenas are used if there are multiple CPUs, which reduces lock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
38 * contention and cache sloshing.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
39 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
40 * + Cache line sharing between arenas is avoided for internal data
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
41 * structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
42 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
43 * + Memory is managed in chunks and runs (chunks can be split into runs),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
44 * rather than as individual pages. This provides a constant-time
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
45 * mechanism for associating allocations with particular arenas.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
46 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
47 * Allocation requests are rounded up to the nearest size class, and no record
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
48 * of the original request size is maintained. Allocations are broken into
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
49 * categories according to size class. Assuming runtime defaults, 4 kB pages
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
50 * and a 16 byte quantum on a 32-bit system, the size classes in each category
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
51 * are as follows:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
52 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
53 * |=====================================|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
54 * | Category | Subcategory | Size |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
55 * |=====================================|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
56 * | Small | Tiny | 2 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
57 * | | | 4 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
58 * | | | 8 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
59 * | |----------------+---------|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
60 * | | Quantum-spaced | 16 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
61 * | | | 32 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
62 * | | | 48 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
63 * | | | ... |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
64 * | | | 480 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
65 * | | | 496 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
66 * | | | 512 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
67 * | |----------------+---------|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
68 * | | Sub-page | 1 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
69 * | | | 2 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
70 * |=====================================|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
71 * | Large | 4 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
72 * | | 8 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
73 * | | 12 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
74 * | | ... |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
75 * | | 1012 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
76 * | | 1016 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
77 * | | 1020 kB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
78 * |=====================================|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
79 * | Huge | 1 MB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
80 * | | 2 MB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
81 * | | 3 MB |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
82 * | | ... |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
83 * |=====================================|
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
84 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
85 * A different mechanism is used for each category:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
86 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
87 * Small : Each size class is segregated into its own set of runs. Each run
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
88 * maintains a bitmap of which regions are free/allocated.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
89 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
90 * Large : Each allocation is backed by a dedicated run. Metadata are stored
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
91 * in the associated arena chunk header maps.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
92 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
93 * Huge : Each allocation is backed by a dedicated contiguous set of chunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
94 * Metadata are stored in a separate red-black tree.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
95 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
96 *******************************************************************************
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
97 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
98
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
99 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
100 * MALLOC_PRODUCTION disables assertions and statistics gathering. It also
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
101 * defaults the A and J runtime options to off. These settings are appropriate
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
102 * for production systems.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
103 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
104 #ifndef MOZ_MEMORY_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
105 # define MALLOC_PRODUCTION
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
106 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
107
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
108 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
109 * Use only one arena by default. Mozilla does not currently make extensive
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
110 * use of concurrent allocation, so the increased fragmentation associated with
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
111 * multiple arenas is not warranted.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
112 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
113 #define MOZ_MEMORY_NARENAS_DEFAULT_ONE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
114
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
115 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
116 * MALLOC_STATS enables statistics calculation, and is required for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
117 * jemalloc_stats().
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
118 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
119 #define MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
120
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
121 #ifndef MALLOC_PRODUCTION
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
122 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
123 * MALLOC_DEBUG enables assertions and other sanity checks, and disables
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
124 * inline functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
125 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
126 # define MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
127
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
128 /* Memory filling (junk/zero). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
129 # define MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
130
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
131 /* Allocation tracing. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
132 # ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
133 # define MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
134 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
135
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
136 /* Support optional abort() on OOM. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
137 # define MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
138
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
139 /* Support SYSV semantics. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
140 # define MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
141 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
142
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
143 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
144 * MALLOC_VALIDATE causes malloc_usable_size() to perform some pointer
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
145 * validation. There are many possible errors that validation does not even
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
146 * attempt to detect.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
147 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
148 #define MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
149
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
150 /* Embed no-op macros that support memory allocation tracking via valgrind. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
151 #ifdef MOZ_VALGRIND
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
152 # define MALLOC_VALGRIND
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
153 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
154 #ifdef MALLOC_VALGRIND
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
155 # include <valgrind/valgrind.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
156 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
157 # define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
158 # define VALGRIND_FREELIKE_BLOCK(addr, rzB)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
159 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
160
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
161 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
162 * MALLOC_BALANCE enables monitoring of arena lock contention and dynamically
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
163 * re-balances arena load if exponentially averaged contention exceeds a
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
164 * certain threshold.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
165 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
166 /* #define MALLOC_BALANCE */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
167
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
168 #if (!defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
169 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
170 * MALLOC_PAGEFILE causes all mmap()ed memory to be backed by temporary
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
171 * files, so that if a chunk is mapped, it is guaranteed to be swappable.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
172 * This avoids asynchronous OOM failures that are due to VM over-commit.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
173 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
174 * XXX OS X over-commits, so we should probably use mmap() instead of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
175 * vm_allocate(), so that MALLOC_PAGEFILE works.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
176 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
177 #define MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
178 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
179
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
180 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
181 /* Write size when initializing a page file. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
182 # define MALLOC_PAGEFILE_WRITE_SIZE 512
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
183 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
184
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
185 #ifdef MOZ_MEMORY_LINUX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
186 #define _GNU_SOURCE /* For mremap(2). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
187 #define issetugid() 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
188 #if 0 /* Enable in order to test decommit code on Linux. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
189 # define MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
190 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
191 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
192
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
193 #ifndef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
194 #include <sys/types.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
195
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
196 #include <errno.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
197 #include <stdlib.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
198 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
199 #include <limits.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
200 #include <stdarg.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
201 #include <stdio.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
202 #include <string.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
203
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
204 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
205 #ifndef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
206 #include <cruntime.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
207 #include <internal.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
208 #include <io.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
209 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
210 #include <crtdefs.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
211 #define SIZE_MAX UINT_MAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
212 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
213 #include <windows.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
214
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
215 #pragma warning( disable: 4267 4996 4146 )
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
216
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
217 #define false FALSE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
218 #define true TRUE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
219 #define inline __inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
220 #define SIZE_T_MAX SIZE_MAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
221 #define STDERR_FILENO 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
222 #define PATH_MAX MAX_PATH
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
223 #define vsnprintf _vsnprintf
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
224
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
225 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
226 static unsigned long tlsIndex = 0xffffffff;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
227 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
228
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
229 #define __thread
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
230 #ifdef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
231 #define _pthread_self() GetCurrentThreadId()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
232 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
233 #define _pthread_self() __threadid()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
234 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
235 #define issetugid() 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
236
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
237 #ifndef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
238 /* use MSVC intrinsics */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
239 #pragma intrinsic(_BitScanForward)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
240 static __forceinline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
241 ffs(int x)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
242 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
243 unsigned long i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
244
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
245 if (_BitScanForward(&i, x) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
246 return (i + 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
247
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
248 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
249 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
250
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
251 /* Implement getenv without using malloc */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
252 static char mozillaMallocOptionsBuf[64];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
253
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
254 #define getenv xgetenv
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
255 static char *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
256 getenv(const char *name)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
257 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
258
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
259 if (GetEnvironmentVariableA(name, (LPSTR)&mozillaMallocOptionsBuf,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
260 sizeof(mozillaMallocOptionsBuf)) > 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
261 return (mozillaMallocOptionsBuf);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
262
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
263 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
264 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
265 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
266
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
267 static void abort() {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
268 DebugBreak();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
269 exit(-3);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
270 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
271
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
272 static int errno = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
273 #define ENOMEM 12
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
274 #define EINVAL 22
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
275
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
276 static char *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
277 getenv(const char *name)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
278 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
279 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
280 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
281
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
282 static int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
283 ffs(int x)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
284 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
285 int ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
286
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
287 if (x == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
288 return 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
289 ret = 2;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
290 if ((x & 0x0000ffff) == 0) { ret += 16; x >>= 16;}
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
291 if ((x & 0x000000ff) == 0) { ret += 8; x >>= 8;}
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
292 if ((x & 0x0000000f) == 0) { ret += 4; x >>= 4;}
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
293 if ((x & 0x00000003) == 0) { ret += 2; x >>= 2;}
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
294 ret -= (x & 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
295
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
296 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
297 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
298 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
299
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
300 typedef unsigned char uint8_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
301 typedef unsigned uint32_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
302 typedef unsigned long long uint64_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
303 typedef unsigned long long uintmax_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
304 typedef long ssize_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
305
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
306 #define MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
307 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
308
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
309 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
310 #ifndef MOZ_MEMORY_SOLARIS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
311 #include <sys/cdefs.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
312 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
313 #ifndef __DECONST
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
314 # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
315 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
316 #ifndef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
317 __FBSDID("$FreeBSD: head/lib/libc/stdlib/malloc.c 180599 2008-07-18 19:35:44Z jasone $");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
318 #include "libc_private.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
319 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
320 # define _LOCK_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
321 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
322 #include "spinlock.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
323 #include "namespace.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
324 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
325 #include <sys/mman.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
326 #ifndef MADV_FREE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
327 # define MADV_FREE MADV_DONTNEED
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
328 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
329 #ifndef MAP_NOSYNC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
330 # define MAP_NOSYNC 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
331 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
332 #include <sys/param.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
333 #ifndef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
334 #include <sys/stddef.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
335 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
336 #include <sys/time.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
337 #include <sys/types.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
338 #ifndef MOZ_MEMORY_SOLARIS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
339 #include <sys/sysctl.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
340 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
341 #include <sys/uio.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
342 #ifndef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
343 #include <sys/ktrace.h> /* Must come after several other sys/ includes. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
344
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
345 #include <machine/atomic.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
346 #include <machine/cpufunc.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
347 #include <machine/vmparam.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
348 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
349
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
350 #include <errno.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
351 #include <limits.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
352 #ifndef SIZE_T_MAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
353 # define SIZE_T_MAX SIZE_MAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
354 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
355 #include <pthread.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
356 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
357 #define _pthread_self pthread_self
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
358 #define _pthread_mutex_init pthread_mutex_init
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
359 #define _pthread_mutex_trylock pthread_mutex_trylock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
360 #define _pthread_mutex_lock pthread_mutex_lock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
361 #define _pthread_mutex_unlock pthread_mutex_unlock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
362 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
363 #include <sched.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
364 #include <stdarg.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
365 #include <stdbool.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
366 #include <stdio.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
367 #include <stdint.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
368 #include <stdlib.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
369 #include <string.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
370 #ifndef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
371 #include <strings.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
372 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
373 #include <unistd.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
374
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
375 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
376 #include <libkern/OSAtomic.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
377 #include <mach/mach_error.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
378 #include <mach/mach_init.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
379 #include <mach/vm_map.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
380 #include <malloc/malloc.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
381 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
382
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
383 #ifndef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
384 #include "un-namespace.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
385 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
386
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
387 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
388
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
389 #include "jemalloc.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
390
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
391 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
392 static const bool __isthreaded = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
393 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
394
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
395 #if defined(MOZ_MEMORY_SOLARIS) && defined(MAP_ALIGN) && !defined(JEMALLOC_NEVER_USES_MAP_ALIGN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
396 #define JEMALLOC_USES_MAP_ALIGN /* Required on Solaris 10. Might improve performance elsewhere. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
397 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
398
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
399 #if defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
400 #define JEMALLOC_USES_MAP_ALIGN /* Required for Windows CE */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
401 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
402
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
403 #define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
404
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
405 #include "qr.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
406 #include "ql.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
407 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
408 /* MSVC++ does not support C99 variable-length arrays. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
409 # define RB_NO_C99_VARARRAYS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
410 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
411 #include "rb.h"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
412
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
413 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
414 /* Disable inlining to make debugging easier. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
415 #ifdef inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
416 #undef inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
417 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
418
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
419 # define inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
420 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
421
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
422 /* Size of stack-allocated buffer passed to strerror_r(). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
423 #define STRERROR_BUF 64
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
424
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
425 /* Minimum alignment of allocations is 2^QUANTUM_2POW_MIN bytes. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
426 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
427 #ifdef MOZ_MEMORY_SIZEOF_PTR_2POW
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
428 # define SIZEOF_PTR_2POW MOZ_MEMORY_SIZEOF_PTR_2POW
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
429 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
430 # define SIZEOF_PTR_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
431 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
432 #define PIC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
433 #ifndef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
434 static const bool __isthreaded = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
435 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
436 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
437 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
438 #if 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
439 #ifdef __i386__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
440 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
441 # define SIZEOF_PTR_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
442 # define CPU_SPINWAIT __asm__ volatile("pause")
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
443 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
444 #ifdef __ia64__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
445 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
446 # define SIZEOF_PTR_2POW 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
447 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
448 #ifdef __alpha__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
449 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
450 # define SIZEOF_PTR_2POW 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
451 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
452 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
453 #ifdef __sparc64__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
454 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
455 # define SIZEOF_PTR_2POW 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
456 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
457 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
458 #ifdef __amd64__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
459 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
460 # define SIZEOF_PTR_2POW 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
461 # define CPU_SPINWAIT __asm__ volatile("pause")
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
462 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
463 #ifdef __arm__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
464 # define QUANTUM_2POW_MIN 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
465 # define SIZEOF_PTR_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
466 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
467 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
468 #ifdef __mips__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
469 # define QUANTUM_2POW_MIN 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
470 # define SIZEOF_PTR_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
471 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
472 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
473 #ifdef __powerpc__
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
474 # define QUANTUM_2POW_MIN 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
475 # define SIZEOF_PTR_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
476 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
477 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
478
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
479 #define SIZEOF_PTR (1U << SIZEOF_PTR_2POW)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
480
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
481 /* sizeof(int) == (1U << SIZEOF_INT_2POW). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
482 #ifndef SIZEOF_INT_2POW
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
483 # define SIZEOF_INT_2POW 2
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
484 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
485
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
486 /* We can't use TLS in non-PIC programs, since TLS relies on loader magic. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
487 #if (!defined(PIC) && !defined(NO_TLS))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
488 # define NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
489 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
490
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
491 #ifdef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
492 /* MALLOC_BALANCE requires TLS. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
493 # ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
494 # undef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
495 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
496 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
497
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
498 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
499 * Size and alignment of memory chunks that are allocated by the OS's virtual
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
500 * memory system.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
501 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
502 #ifdef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
503 #define CHUNK_2POW_DEFAULT 21
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
504 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
505 #define CHUNK_2POW_DEFAULT 20
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
506 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
507 /* Maximum number of dirty pages per arena. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
508 #define DIRTY_MAX_DEFAULT (1U << 10)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
509
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
510 /* Default reserve chunks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
511 #define RESERVE_MIN_2POW_DEFAULT 1
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
512 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
513 * Default range (in chunks) between reserve_min and reserve_max, in addition
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
514 * to the mandatory one chunk per arena.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
515 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
516 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
517 # define RESERVE_RANGE_2POW_DEFAULT 5
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
518 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
519 # define RESERVE_RANGE_2POW_DEFAULT 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
520 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
521
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
522 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
523 * Maximum size of L1 cache line. This is used to avoid cache line aliasing,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
524 * so over-estimates are okay (up to a point), but under-estimates will
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
525 * negatively affect performance.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
526 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
527 #define CACHELINE_2POW 6
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
528 #define CACHELINE ((size_t)(1U << CACHELINE_2POW))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
529
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
530 /* Smallest size class to support. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
531 #define TINY_MIN_2POW 1
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
532
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
533 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
534 * Maximum size class that is a multiple of the quantum, but not (necessarily)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
535 * a power of 2. Above this size, allocations are rounded up to the nearest
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
536 * power of 2.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
537 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
538 #define SMALL_MAX_2POW_DEFAULT 9
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
539 #define SMALL_MAX_DEFAULT (1U << SMALL_MAX_2POW_DEFAULT)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
540
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
541 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
542 * RUN_MAX_OVRHD indicates maximum desired run header overhead. Runs are sized
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
543 * as small as possible such that this setting is still honored, without
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
544 * violating other constraints. The goal is to make runs as small as possible
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
545 * without exceeding a per run external fragmentation threshold.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
546 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
547 * We use binary fixed point math for overhead computations, where the binary
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
548 * point is implicitly RUN_BFP bits to the left.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
549 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
550 * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
551 * honored for some/all object sizes, since there is one bit of header overhead
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
552 * per object (plus a constant). This constraint is relaxed (ignored) for runs
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
553 * that are so small that the per-region overhead is greater than:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
554 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
555 * (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
556 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
557 #define RUN_BFP 12
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
558 /* \/ Implicit binary fixed point. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
559 #define RUN_MAX_OVRHD 0x0000003dU
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
560 #define RUN_MAX_OVRHD_RELAX 0x00001800U
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
561
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
562 /* Put a cap on small object run size. This overrides RUN_MAX_OVRHD. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
563 #define RUN_MAX_SMALL_2POW 15
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
564 #define RUN_MAX_SMALL (1U << RUN_MAX_SMALL_2POW)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
565
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
566 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
567 * Hyper-threaded CPUs may need a special instruction inside spin loops in
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
568 * order to yield to another virtual CPU. If no such instruction is defined
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
569 * above, make CPU_SPINWAIT a no-op.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
570 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
571 #ifndef CPU_SPINWAIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
572 # define CPU_SPINWAIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
573 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
574
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
575 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
576 * Adaptive spinning must eventually switch to blocking, in order to avoid the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
577 * potential for priority inversion deadlock. Backing off past a certain point
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
578 * can actually waste time.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
579 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
580 #define SPIN_LIMIT_2POW 11
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
581
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
582 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
583 * Conversion from spinning to blocking is expensive; we use (1U <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
584 * BLOCK_COST_2POW) to estimate how many more times costly blocking is than
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
585 * worst-case spinning.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
586 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
587 #define BLOCK_COST_2POW 4
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
588
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
589 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
590 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
591 * We use an exponential moving average to track recent lock contention,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
592 * where the size of the history window is N, and alpha=2/(N+1).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
593 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
594 * Due to integer math rounding, very small values here can cause
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
595 * substantial degradation in accuracy, thus making the moving average decay
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
596 * faster than it would with precise calculation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
597 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
598 # define BALANCE_ALPHA_INV_2POW 9
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
599
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
600 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
601 * Threshold value for the exponential moving contention average at which to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
602 * re-assign a thread.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
603 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
604 # define BALANCE_THRESHOLD_DEFAULT (1U << (SPIN_LIMIT_2POW-4))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
605 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
606
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
607 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
608
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
609 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
610 * Mutexes based on spinlocks. We can't use normal pthread spinlocks in all
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
611 * places, because they require malloc()ed memory, which causes bootstrapping
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
612 * issues in some cases.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
613 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
614 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
615 #define malloc_mutex_t CRITICAL_SECTION
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
616 #define malloc_spinlock_t CRITICAL_SECTION
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
617 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
618 typedef struct {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
619 OSSpinLock lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
620 } malloc_mutex_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
621 typedef struct {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
622 OSSpinLock lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
623 } malloc_spinlock_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
624 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
625 typedef pthread_mutex_t malloc_mutex_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
626 typedef pthread_mutex_t malloc_spinlock_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
627 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
628 /* XXX these should #ifdef these for freebsd (and linux?) only */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
629 typedef struct {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
630 spinlock_t lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
631 } malloc_mutex_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
632 typedef malloc_spinlock_t malloc_mutex_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
633 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
634
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
635 /* Set to true once the allocator has been initialized. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
636 static bool malloc_initialized = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
637
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
638 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
639 /* No init lock for Windows. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
640 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
641 static malloc_mutex_t init_lock = {OS_SPINLOCK_INIT};
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
642 #elif defined(MOZ_MEMORY_LINUX)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
643 static malloc_mutex_t init_lock = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
644 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
645 static malloc_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
646 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
647 static malloc_mutex_t init_lock = {_SPINLOCK_INITIALIZER};
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
648 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
649
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
650 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
651 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
652 * Statistics data structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
653 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
654
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
655 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
656
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
657 typedef struct malloc_bin_stats_s malloc_bin_stats_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
658 struct malloc_bin_stats_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
659 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
660 * Number of allocation requests that corresponded to the size of this
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
661 * bin.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
662 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
663 uint64_t nrequests;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
664
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
665 /* Total number of runs created for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
666 uint64_t nruns;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
667
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
668 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
669 * Total number of runs reused by extracting them from the runs tree for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
670 * this bin's size class.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
671 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
672 uint64_t reruns;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
673
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
674 /* High-water mark for this bin. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
675 unsigned long highruns;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
676
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
677 /* Current number of runs in this bin. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
678 unsigned long curruns;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
679 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
680
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
681 typedef struct arena_stats_s arena_stats_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
682 struct arena_stats_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
683 /* Number of bytes currently mapped. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
684 size_t mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
685
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
686 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
687 * Total number of purge sweeps, total number of madvise calls made,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
688 * and total pages purged in order to keep dirty unused memory under
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
689 * control.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
690 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
691 uint64_t npurge;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
692 uint64_t nmadvise;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
693 uint64_t purged;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
694 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
695 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
696 * Total number of decommit/commit operations, and total number of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
697 * pages decommitted.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
698 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
699 uint64_t ndecommit;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
700 uint64_t ncommit;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
701 uint64_t decommitted;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
702 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
703
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
704 /* Per-size-category statistics. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
705 size_t allocated_small;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
706 uint64_t nmalloc_small;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
707 uint64_t ndalloc_small;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
708
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
709 size_t allocated_large;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
710 uint64_t nmalloc_large;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
711 uint64_t ndalloc_large;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
712
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
713 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
714 /* Number of times this arena reassigned a thread due to contention. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
715 uint64_t nbalance;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
716 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
717 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
718
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
719 typedef struct chunk_stats_s chunk_stats_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
720 struct chunk_stats_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
721 /* Number of chunks that were allocated. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
722 uint64_t nchunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
723
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
724 /* High-water mark for number of chunks allocated. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
725 unsigned long highchunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
726
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
727 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
728 * Current number of chunks allocated. This value isn't maintained for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
729 * any other purpose, so keep track of it in order to be able to set
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
730 * highchunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
731 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
732 unsigned long curchunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
733 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
734
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
735 #endif /* #ifdef MALLOC_STATS */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
736
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
737 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
738 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
739 * Extent data structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
740 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
741
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
742 /* Tree of extents. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
743 typedef struct extent_node_s extent_node_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
744 struct extent_node_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
745 /* Linkage for the size/address-ordered tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
746 rb_node(extent_node_t) link_szad;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
747
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
748 /* Linkage for the address-ordered tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
749 rb_node(extent_node_t) link_ad;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
750
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
751 /* Pointer to the extent that this tree node is responsible for. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
752 void *addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
753
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
754 /* Total region size. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
755 size_t size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
756 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
757 typedef rb_tree(extent_node_t) extent_tree_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
758
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
759 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
760 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
761 * Radix tree data structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
762 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
763
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
764 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
765 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
766 * Size of each radix tree node (must be a power of 2). This impacts tree
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
767 * depth.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
768 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
769 # if (SIZEOF_PTR == 4)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
770 # define MALLOC_RTREE_NODESIZE (1U << 14)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
771 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
772 # define MALLOC_RTREE_NODESIZE CACHELINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
773 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
774
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
775 typedef struct malloc_rtree_s malloc_rtree_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
776 struct malloc_rtree_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
777 malloc_spinlock_t lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
778 void **root;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
779 unsigned height;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
780 unsigned level2bits[1]; /* Dynamically sized. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
781 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
782 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
783
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
784 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
785 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
786 * Reserve data structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
787 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
788
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
789 /* Callback registration. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
790 typedef struct reserve_reg_s reserve_reg_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
791 struct reserve_reg_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
792 /* Linkage for list of all registered callbacks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
793 ql_elm(reserve_reg_t) link;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
794
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
795 /* Callback function pointer. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
796 reserve_cb_t *cb;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
797
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
798 /* Opaque application data pointer. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
799 void *ctx;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
800
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
801 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
802 * Sequence number of condition notification most recently sent to this
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
803 * callback.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
804 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
805 uint64_t seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
806 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
807
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
808 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
809 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
810 * Arena data structures.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
811 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
812
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
813 typedef struct arena_s arena_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
814 typedef struct arena_bin_s arena_bin_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
815
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
816 /* Each element of the chunk map corresponds to one page within the chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
817 typedef struct arena_chunk_map_s arena_chunk_map_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
818 struct arena_chunk_map_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
819 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
820 * Linkage for run trees. There are two disjoint uses:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
821 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
822 * 1) arena_t's runs_avail tree.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
823 * 2) arena_run_t conceptually uses this linkage for in-use non-full
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
824 * runs, rather than directly embedding linkage.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
825 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
826 rb_node(arena_chunk_map_t) link;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
827
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
828 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
829 * Run address (or size) and various flags are stored together. The bit
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
830 * layout looks like (assuming 32-bit system):
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
831 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
832 * ???????? ???????? ????---- --ckdzla
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
833 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
834 * ? : Unallocated: Run address for first/last pages, unset for internal
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
835 * pages.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
836 * Small: Run address.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
837 * Large: Run size for first page, unset for trailing pages.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
838 * - : Unused.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
839 * c : decommitted?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
840 * k : key?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
841 * d : dirty?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
842 * z : zeroed?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
843 * l : large?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
844 * a : allocated?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
845 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
846 * Following are example bit patterns for the three types of runs.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
847 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
848 * r : run address
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
849 * s : run size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
850 * x : don't care
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
851 * - : 0
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
852 * [cdzla] : bit set
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
853 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
854 * Unallocated:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
855 * ssssssss ssssssss ssss---- --c-----
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
856 * xxxxxxxx xxxxxxxx xxxx---- ----d---
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
857 * ssssssss ssssssss ssss---- -----z--
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
858 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
859 * Small:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
860 * rrrrrrrr rrrrrrrr rrrr---- -------a
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
861 * rrrrrrrr rrrrrrrr rrrr---- -------a
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
862 * rrrrrrrr rrrrrrrr rrrr---- -------a
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
863 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
864 * Large:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
865 * ssssssss ssssssss ssss---- ------la
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
866 * -------- -------- -------- ------la
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
867 * -------- -------- -------- ------la
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
868 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
869 size_t bits;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
870 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
871 #define CHUNK_MAP_DECOMMITTED ((size_t)0x20U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
872 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
873 #define CHUNK_MAP_KEY ((size_t)0x10U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
874 #define CHUNK_MAP_DIRTY ((size_t)0x08U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
875 #define CHUNK_MAP_ZEROED ((size_t)0x04U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
876 #define CHUNK_MAP_LARGE ((size_t)0x02U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
877 #define CHUNK_MAP_ALLOCATED ((size_t)0x01U)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
878 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
879 typedef rb_tree(arena_chunk_map_t) arena_avail_tree_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
880 typedef rb_tree(arena_chunk_map_t) arena_run_tree_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
881
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
882 /* Arena chunk header. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
883 typedef struct arena_chunk_s arena_chunk_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
884 struct arena_chunk_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
885 /* Arena that owns the chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
886 arena_t *arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
887
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
888 /* Linkage for the arena's chunks_dirty tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
889 rb_node(arena_chunk_t) link_dirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
890
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
891 /* Number of dirty pages. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
892 size_t ndirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
893
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
894 /* Map of pages within chunk that keeps track of free/large/small. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
895 arena_chunk_map_t map[1]; /* Dynamically sized. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
896 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
897 typedef rb_tree(arena_chunk_t) arena_chunk_tree_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
898
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
899 typedef struct arena_run_s arena_run_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
900 struct arena_run_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
901 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
902 uint32_t magic;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
903 # define ARENA_RUN_MAGIC 0x384adf93
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
904 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
905
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
906 /* Bin this run is associated with. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
907 arena_bin_t *bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
908
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
909 /* Index of first element that might have a free region. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
910 unsigned regs_minelm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
911
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
912 /* Number of free regions in run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
913 unsigned nfree;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
914
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
915 /* Bitmask of in-use regions (0: in use, 1: free). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
916 unsigned regs_mask[1]; /* Dynamically sized. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
917 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
918
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
919 struct arena_bin_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
920 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
921 * Current run being used to service allocations of this bin's size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
922 * class.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
923 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
924 arena_run_t *runcur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
925
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
926 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
927 * Tree of non-full runs. This tree is used when looking for an
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
928 * existing run when runcur is no longer usable. We choose the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
929 * non-full run that is lowest in memory; this policy tends to keep
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
930 * objects packed well, and it can also help reduce the number of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
931 * almost-empty chunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
932 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
933 arena_run_tree_t runs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
934
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
935 /* Size of regions in a run for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
936 size_t reg_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
937
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
938 /* Total size of a run for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
939 size_t run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
940
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
941 /* Total number of regions in a run for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
942 uint32_t nregs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
943
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
944 /* Number of elements in a run's regs_mask for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
945 uint32_t regs_mask_nelms;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
946
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
947 /* Offset of first region in a run for this bin's size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
948 uint32_t reg0_offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
949
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
950 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
951 /* Bin statistics. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
952 malloc_bin_stats_t stats;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
953 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
954 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
955
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
956 struct arena_s {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
957 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
958 uint32_t magic;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
959 # define ARENA_MAGIC 0x947d3d24
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
960 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
961
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
962 /* All operations on this arena require that lock be locked. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
963 #ifdef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
964 malloc_spinlock_t lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
965 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
966 pthread_mutex_t lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
967 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
968
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
969 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
970 arena_stats_t stats;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
971 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
972
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
973 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
974 * Chunk allocation sequence number, used to detect races with other
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
975 * threads during chunk allocation, and then discard unnecessary chunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
976 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
977 uint64_t chunk_seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
978
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
979 /* Tree of dirty-page-containing chunks this arena manages. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
980 arena_chunk_tree_t chunks_dirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
981
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
982 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
983 * In order to avoid rapid chunk allocation/deallocation when an arena
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
984 * oscillates right on the cusp of needing a new chunk, cache the most
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
985 * recently freed chunk. The spare is left in the arena's chunk trees
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
986 * until it is deleted.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
987 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
988 * There is one spare chunk per arena, rather than one spare total, in
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
989 * order to avoid interactions between multiple threads that could make
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
990 * a single spare inadequate.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
991 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
992 arena_chunk_t *spare;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
993
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
994 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
995 * Current count of pages within unused runs that are potentially
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
996 * dirty, and for which madvise(... MADV_FREE) has not been called. By
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
997 * tracking this, we can institute a limit on how much dirty unused
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
998 * memory is mapped for each arena.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
999 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1000 size_t ndirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1001
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1002 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1003 * Size/address-ordered tree of this arena's available runs. This tree
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1004 * is used for first-best-fit run allocation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1005 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1006 arena_avail_tree_t runs_avail;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1007
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1008 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1009 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1010 * The arena load balancing machinery needs to keep track of how much
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1011 * lock contention there is. This value is exponentially averaged.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1012 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1013 uint32_t contention;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1014 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1015
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1016 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1017 * bins is used to store rings of free regions of the following sizes,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1018 * assuming a 16-byte quantum, 4kB pagesize, and default MALLOC_OPTIONS.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1019 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1020 * bins[i] | size |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1021 * --------+------+
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1022 * 0 | 2 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1023 * 1 | 4 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1024 * 2 | 8 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1025 * --------+------+
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1026 * 3 | 16 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1027 * 4 | 32 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1028 * 5 | 48 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1029 * 6 | 64 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1030 * : :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1031 * : :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1032 * 33 | 496 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1033 * 34 | 512 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1034 * --------+------+
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1035 * 35 | 1024 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1036 * 36 | 2048 |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1037 * --------+------+
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1038 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1039 arena_bin_t bins[1]; /* Dynamically sized. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1040 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1041
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1042 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1043 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1044 * Data.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1045 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1046
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1047 /* Number of CPUs. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1048 static unsigned ncpus;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1049
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1050 /* VM page size. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1051 static size_t pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1052 static size_t pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1053 static size_t pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1054
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1055 /* Various bin-related settings. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1056 static size_t bin_maxclass; /* Max size class for bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1057 static unsigned ntbins; /* Number of (2^n)-spaced tiny bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1058 static unsigned nqbins; /* Number of quantum-spaced bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1059 static unsigned nsbins; /* Number of (2^n)-spaced sub-page bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1060 static size_t small_min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1061 static size_t small_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1062
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1063 /* Various quantum-related settings. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1064 static size_t quantum;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1065 static size_t quantum_mask; /* (quantum - 1). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1066
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1067 /* Various chunk-related settings. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1068 static size_t chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1069 static size_t chunksize_mask; /* (chunksize - 1). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1070 static size_t chunk_npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1071 static size_t arena_chunk_header_npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1072 static size_t arena_maxclass; /* Max size class for arenas. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1073
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1074 /********/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1075 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1076 * Chunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1077 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1078
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1079 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1080 static malloc_rtree_t *chunk_rtree;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1081 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1082
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1083 /* Protects chunk-related data structures. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1084 static malloc_mutex_t huge_mtx;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1085
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1086 /* Tree of chunks that are stand-alone huge allocations. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1087 static extent_tree_t huge;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1088
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1089 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1090 /* Huge allocation statistics. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1091 static uint64_t huge_nmalloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1092 static uint64_t huge_ndalloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1093 static size_t huge_allocated;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1094 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1095
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1096 /****************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1097 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1098 * Memory reserve.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1099 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1100
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1101 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1102 static char pagefile_templ[PATH_MAX];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1103 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1104
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1105 /* Protects reserve-related data structures. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1106 static malloc_mutex_t reserve_mtx;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1107
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1108 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1109 * Bounds on acceptable reserve size, and current reserve size. Reserve
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1110 * depletion may cause (reserve_cur < reserve_min).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1111 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1112 static size_t reserve_min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1113 static size_t reserve_cur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1114 static size_t reserve_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1115
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1116 /* List of registered callbacks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1117 static ql_head(reserve_reg_t) reserve_regs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1118
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1119 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1120 * Condition notification sequence number, used to determine whether all
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1121 * registered callbacks have been notified of the most current condition.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1122 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1123 static uint64_t reserve_seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1124
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1125 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1126 * Trees of chunks currently in the memory reserve. Depending on function,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1127 * different tree orderings are needed, which is why there are two trees with
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1128 * the same contents.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1129 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1130 static extent_tree_t reserve_chunks_szad;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1131 static extent_tree_t reserve_chunks_ad;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1132
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1133 /****************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1134 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1135 * base (internal allocation).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1136 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1137
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1138 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1139 * Current pages that are being used for internal memory allocations. These
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1140 * pages are carved up in cacheline-size quanta, so that there is no chance of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1141 * false cache line sharing.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1142 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1143 static void *base_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1144 static void *base_next_addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1145 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1146 static void *base_next_decommitted;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1147 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1148 static void *base_past_addr; /* Addr immediately past base_pages. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1149 static extent_node_t *base_nodes;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1150 static reserve_reg_t *base_reserve_regs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1151 static malloc_mutex_t base_mtx;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1152 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1153 static size_t base_mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1154 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1155
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1156 /********/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1157 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1158 * Arenas.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1159 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1160
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1161 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1162 * Arenas that are used to service external requests. Not all elements of the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1163 * arenas array are necessarily used; arenas are created lazily as needed.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1164 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1165 static arena_t **arenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1166 static unsigned narenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1167 static unsigned narenas_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1168 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1169 # ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1170 static unsigned narenas_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1171 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1172 static unsigned next_arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1173 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1174 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1175 #ifdef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1176 static malloc_spinlock_t arenas_lock; /* Protects arenas initialization. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1177 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1178 static pthread_mutex_t arenas_lock; /* Protects arenas initialization. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1179 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1180
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1181 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1182 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1183 * Map of pthread_self() --> arenas[???], used for selecting an arena to use
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1184 * for allocations.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1185 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1186 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1187 static __thread arena_t *arenas_map;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1188 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1189 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1190
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1191 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1192 /* Chunk statistics. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1193 static chunk_stats_t stats_chunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1194 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1195
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1196 /*******************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1197 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1198 * Runtime configuration options.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1199 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1200 const char *_malloc_options;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1201
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1202 #ifndef MALLOC_PRODUCTION
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1203 static bool opt_abort = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1204 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1205 static bool opt_junk = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1206 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1207 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1208 static bool opt_abort = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1209 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1210 static bool opt_junk = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1211 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1212 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1213 static size_t opt_dirty_max = DIRTY_MAX_DEFAULT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1214 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1215 static uint64_t opt_balance_threshold = BALANCE_THRESHOLD_DEFAULT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1216 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1217 static bool opt_print_stats = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1218 static size_t opt_quantum_2pow = QUANTUM_2POW_MIN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1219 static size_t opt_small_max_2pow = SMALL_MAX_2POW_DEFAULT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1220 static size_t opt_chunk_2pow = CHUNK_2POW_DEFAULT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1221 static int opt_reserve_min_lshift = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1222 static int opt_reserve_range_lshift = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1223 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1224 static bool opt_pagefile = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1225 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1226 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1227 static bool opt_utrace = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1228 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1229 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1230 static bool opt_sysv = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1231 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1232 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1233 static bool opt_xmalloc = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1234 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1235 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1236 static bool opt_zero = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1237 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1238 static int opt_narenas_lshift = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1239
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1240 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1241 typedef struct {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1242 void *p;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1243 size_t s;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1244 void *r;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1245 } malloc_utrace_t;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1246
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1247 #define UTRACE(a, b, c) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1248 if (opt_utrace) { \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1249 malloc_utrace_t ut; \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1250 ut.p = (a); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1251 ut.s = (b); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1252 ut.r = (c); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1253 utrace(&ut, sizeof(ut)); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1254 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1255 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1256 #define UTRACE(a, b, c)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1257 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1258
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1259 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1260 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1261 * Begin function prototypes for non-inline static functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1262 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1263
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1264 static char *umax2s(uintmax_t x, char *s);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1265 static bool malloc_mutex_init(malloc_mutex_t *mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1266 static bool malloc_spin_init(malloc_spinlock_t *lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1267 static void wrtmessage(const char *p1, const char *p2, const char *p3,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1268 const char *p4);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1269 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1270 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1271 /* Avoid namespace collision with OS X's malloc APIs. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1272 #define malloc_printf moz_malloc_printf
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1273 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1274 static void malloc_printf(const char *format, ...);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1275 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1276 static bool base_pages_alloc_mmap(size_t minsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1277 static bool base_pages_alloc(size_t minsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1278 static void *base_alloc(size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1279 static void *base_calloc(size_t number, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1280 static extent_node_t *base_node_alloc(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1281 static void base_node_dealloc(extent_node_t *node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1282 static reserve_reg_t *base_reserve_reg_alloc(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1283 static void base_reserve_reg_dealloc(reserve_reg_t *reg);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1284 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1285 static void stats_print(arena_t *arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1286 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1287 static void *pages_map(void *addr, size_t size, int pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1288 static void pages_unmap(void *addr, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1289 static void *chunk_alloc_mmap(size_t size, bool pagefile);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1290 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1291 static int pagefile_init(size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1292 static void pagefile_close(int pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1293 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1294 static void *chunk_recycle_reserve(size_t size, bool zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1295 static void *chunk_alloc(size_t size, bool zero, bool pagefile);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1296 static extent_node_t *chunk_dealloc_reserve(void *chunk, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1297 static void chunk_dealloc_mmap(void *chunk, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1298 static void chunk_dealloc(void *chunk, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1299 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1300 static arena_t *choose_arena_hard(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1301 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1302 static void arena_run_split(arena_t *arena, arena_run_t *run, size_t size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1303 bool large, bool zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1304 static void arena_chunk_init(arena_t *arena, arena_chunk_t *chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1305 static void arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1306 static arena_run_t *arena_run_alloc(arena_t *arena, arena_bin_t *bin,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1307 size_t size, bool large, bool zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1308 static void arena_purge(arena_t *arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1309 static void arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1310 static void arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1311 arena_run_t *run, size_t oldsize, size_t newsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1312 static void arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1313 arena_run_t *run, size_t oldsize, size_t newsize, bool dirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1314 static arena_run_t *arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1315 static void *arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1316 static size_t arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1317 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1318 static void arena_lock_balance_hard(arena_t *arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1319 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1320 static void *arena_malloc_large(arena_t *arena, size_t size, bool zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1321 static void *arena_palloc(arena_t *arena, size_t alignment, size_t size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1322 size_t alloc_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1323 static size_t arena_salloc(const void *ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1324 static void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1325 void *ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1326 static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1327 void *ptr, size_t size, size_t oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1328 static bool arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1329 void *ptr, size_t size, size_t oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1330 static bool arena_ralloc_large(void *ptr, size_t size, size_t oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1331 static void *arena_ralloc(void *ptr, size_t size, size_t oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1332 static bool arena_new(arena_t *arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1333 static arena_t *arenas_extend(unsigned ind);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1334 static void *huge_malloc(size_t size, bool zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1335 static void *huge_palloc(size_t alignment, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1336 static void *huge_ralloc(void *ptr, size_t size, size_t oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1337 static void huge_dalloc(void *ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1338 static void malloc_print_stats(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1339 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1340 static
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1341 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1342 bool malloc_init_hard(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1343 static void reserve_shrink(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1344 static uint64_t reserve_notify(reserve_cnd_t cnd, size_t size, uint64_t seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1345 static uint64_t reserve_crit(size_t size, const char *fname, uint64_t seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1346 static void reserve_fail(size_t size, const char *fname);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1347
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1348 void _malloc_prefork(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1349 void _malloc_postfork(void);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1350
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1351 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1352 * End function prototypes.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1353 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1354 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1355
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1356 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1357 * umax2s() provides minimal integer printing functionality, which is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1358 * especially useful for situations where allocation in vsnprintf() calls would
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1359 * potentially cause deadlock.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1360 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1361 #define UMAX2S_BUFSIZE 21
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1362 static char *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1363 umax2s(uintmax_t x, char *s)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1364 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1365 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1366
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1367 i = UMAX2S_BUFSIZE - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1368 s[i] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1369 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1370 i--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1371 s[i] = "0123456789"[x % 10];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1372 x /= 10;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1373 } while (x > 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1374
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1375 return (&s[i]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1376 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1377
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1378 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1379 wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1380 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1381 #ifdef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1382 wchar_t buf[1024];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1383 #define WRT_PRINT(s) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1384 MultiByteToWideChar(CP_ACP, 0, s, -1, buf, 1024); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1385 OutputDebugStringW(buf)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1386
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1387 WRT_PRINT(p1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1388 WRT_PRINT(p2);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1389 WRT_PRINT(p3);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1390 WRT_PRINT(p4);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1391 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1392 #if defined(MOZ_MEMORY) && !defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1393 #define _write write
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1394 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1395 _write(STDERR_FILENO, p1, (unsigned int) strlen(p1));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1396 _write(STDERR_FILENO, p2, (unsigned int) strlen(p2));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1397 _write(STDERR_FILENO, p3, (unsigned int) strlen(p3));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1398 _write(STDERR_FILENO, p4, (unsigned int) strlen(p4));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1399 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1400
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1401 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1402
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1403 #define _malloc_message malloc_message
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1404
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1405 void (*_malloc_message)(const char *p1, const char *p2, const char *p3,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1406 const char *p4) = wrtmessage;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1407
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1408 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1409 # define assert(e) do { \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1410 if (!(e)) { \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1411 char line_buf[UMAX2S_BUFSIZE]; \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1412 _malloc_message(__FILE__, ":", umax2s(__LINE__, \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1413 line_buf), ": Failed assertion: "); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1414 _malloc_message("\"", #e, "\"\n", ""); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1415 abort(); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1416 } \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1417 } while (0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1418 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1419 #define assert(e)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1420 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1421
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1422 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1423 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1424 * Begin mutex. We can't use normal pthread mutexes in all places, because
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1425 * they require malloc()ed memory, which causes bootstrapping issues in some
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1426 * cases.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1427 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1428
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1429 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1430 malloc_mutex_init(malloc_mutex_t *mutex)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1431 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1432 #if defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1433 InitializeCriticalSection(mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1434 #elif defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1435 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1436 if (! __crtInitCritSecAndSpinCount(mutex, _CRT_SPINCOUNT))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1437 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1438 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1439 mutex->lock = OS_SPINLOCK_INIT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1440 #elif defined(MOZ_MEMORY_LINUX)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1441 pthread_mutexattr_t attr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1442 if (pthread_mutexattr_init(&attr) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1443 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1444 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1445 if (pthread_mutex_init(mutex, &attr) != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1446 pthread_mutexattr_destroy(&attr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1447 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1448 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1449 pthread_mutexattr_destroy(&attr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1450 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1451 if (pthread_mutex_init(mutex, NULL) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1452 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1453 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1454 static const spinlock_t lock = _SPINLOCK_INITIALIZER;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1455
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1456 mutex->lock = lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1457 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1458 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1459 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1460
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1461 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1462 malloc_mutex_lock(malloc_mutex_t *mutex)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1463 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1464
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1465 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1466 EnterCriticalSection(mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1467 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1468 OSSpinLockLock(&mutex->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1469 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1470 pthread_mutex_lock(mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1471 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1472 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1473 _SPINLOCK(&mutex->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1474 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1475 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1476
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1477 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1478 malloc_mutex_unlock(malloc_mutex_t *mutex)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1479 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1480
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1481 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1482 LeaveCriticalSection(mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1483 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1484 OSSpinLockUnlock(&mutex->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1485 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1486 pthread_mutex_unlock(mutex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1487 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1488 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1489 _SPINUNLOCK(&mutex->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1490 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1491 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1492
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1493 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1494 malloc_spin_init(malloc_spinlock_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1495 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1496 #if defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1497 InitializeCriticalSection(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1498 #elif defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1499 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1500 if (! __crtInitCritSecAndSpinCount(lock, _CRT_SPINCOUNT))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1501 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1502 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1503 lock->lock = OS_SPINLOCK_INIT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1504 #elif defined(MOZ_MEMORY_LINUX)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1505 pthread_mutexattr_t attr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1506 if (pthread_mutexattr_init(&attr) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1507 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1508 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1509 if (pthread_mutex_init(lock, &attr) != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1510 pthread_mutexattr_destroy(&attr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1511 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1512 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1513 pthread_mutexattr_destroy(&attr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1514 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1515 if (pthread_mutex_init(lock, NULL) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1516 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1517 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1518 lock->lock = _SPINLOCK_INITIALIZER;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1519 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1520 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1521 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1522
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1523 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1524 malloc_spin_lock(malloc_spinlock_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1525 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1526
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1527 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1528 EnterCriticalSection(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1529 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1530 OSSpinLockLock(&lock->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1531 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1532 pthread_mutex_lock(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1533 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1534 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1535 _SPINLOCK(&lock->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1536 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1537 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1538
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1539 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1540 malloc_spin_unlock(malloc_spinlock_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1541 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1542 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1543 LeaveCriticalSection(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1544 #elif defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1545 OSSpinLockUnlock(&lock->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1546 #elif defined(MOZ_MEMORY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1547 pthread_mutex_unlock(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1548 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1549 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1550 _SPINUNLOCK(&lock->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1551 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1552 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1553
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1554 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1555 * End mutex.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1556 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1557 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1558 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1559 * Begin spin lock. Spin locks here are actually adaptive mutexes that block
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1560 * after a period of spinning, because unbounded spinning would allow for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1561 * priority inversion.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1562 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1563
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1564 #if defined(MOZ_MEMORY) && !defined(MOZ_MEMORY_DARWIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1565 # define malloc_spin_init malloc_mutex_init
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1566 # define malloc_spin_lock malloc_mutex_lock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1567 # define malloc_spin_unlock malloc_mutex_unlock
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1568 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1569
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1570 #ifndef MOZ_MEMORY
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1571 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1572 * We use an unpublished interface to initialize pthread mutexes with an
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1573 * allocation callback, in order to avoid infinite recursion.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1574 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1575 int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1576 void *(calloc_cb)(size_t, size_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1577
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1578 __weak_reference(_pthread_mutex_init_calloc_cb_stub,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1579 _pthread_mutex_init_calloc_cb);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1580
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1581 int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1582 _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1583 void *(calloc_cb)(size_t, size_t))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1584 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1585
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1586 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1587 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1588
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1589 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1590 malloc_spin_init(pthread_mutex_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1591 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1592
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1593 if (_pthread_mutex_init_calloc_cb(lock, base_calloc) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1594 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1595
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1596 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1597 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1598
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1599 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1600 malloc_spin_lock(pthread_mutex_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1601 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1602 unsigned ret = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1603
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1604 if (__isthreaded) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1605 if (_pthread_mutex_trylock(lock) != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1606 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1607 volatile unsigned j;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1608
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1609 /* Exponentially back off. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1610 for (i = 1; i <= SPIN_LIMIT_2POW; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1611 for (j = 0; j < (1U << i); j++)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1612 ret++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1613
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1614 CPU_SPINWAIT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1615 if (_pthread_mutex_trylock(lock) == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1616 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1617 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1618
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1619 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1620 * Spinning failed. Block until the lock becomes
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1621 * available, in order to avoid indefinite priority
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1622 * inversion.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1623 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1624 _pthread_mutex_lock(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1625 assert((ret << BLOCK_COST_2POW) != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1626 return (ret << BLOCK_COST_2POW);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1627 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1628 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1629
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1630 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1631 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1632
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1633 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1634 malloc_spin_unlock(pthread_mutex_t *lock)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1635 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1636
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1637 if (__isthreaded)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1638 _pthread_mutex_unlock(lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1639 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1640 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1641
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1642 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1643 * End spin lock.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1644 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1645 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1646 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1647 * Begin Utility functions/macros.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1648 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1649
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1650 /* Return the chunk address for allocation address a. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1651 #define CHUNK_ADDR2BASE(a) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1652 ((void *)((uintptr_t)(a) & ~chunksize_mask))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1653
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1654 /* Return the chunk offset of address a. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1655 #define CHUNK_ADDR2OFFSET(a) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1656 ((size_t)((uintptr_t)(a) & chunksize_mask))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1657
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1658 /* Return the smallest chunk multiple that is >= s. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1659 #define CHUNK_CEILING(s) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1660 (((s) + chunksize_mask) & ~chunksize_mask)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1661
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1662 /* Return the smallest cacheline multiple that is >= s. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1663 #define CACHELINE_CEILING(s) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1664 (((s) + (CACHELINE - 1)) & ~(CACHELINE - 1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1665
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1666 /* Return the smallest quantum multiple that is >= a. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1667 #define QUANTUM_CEILING(a) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1668 (((a) + quantum_mask) & ~quantum_mask)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1669
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1670 /* Return the smallest pagesize multiple that is >= s. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1671 #define PAGE_CEILING(s) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1672 (((s) + pagesize_mask) & ~pagesize_mask)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1673
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1674 /* Compute the smallest power of 2 that is >= x. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1675 static inline size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1676 pow2_ceil(size_t x)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1677 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1678
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1679 x--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1680 x |= x >> 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1681 x |= x >> 2;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1682 x |= x >> 4;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1683 x |= x >> 8;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1684 x |= x >> 16;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1685 #if (SIZEOF_PTR == 8)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1686 x |= x >> 32;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1687 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1688 x++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1689 return (x);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1690 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1691
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1692 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1693 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1694 * Use a simple linear congruential pseudo-random number generator:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1695 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1696 * prn(y) = (a*x + c) % m
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1697 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1698 * where the following constants ensure maximal period:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1699 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1700 * a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1701 * c == Odd number (relatively prime to 2^n).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1702 * m == 2^32
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1703 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1704 * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1705 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1706 * This choice of m has the disadvantage that the quality of the bits is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1707 * proportional to bit position. For example. the lowest bit has a cycle of 2,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1708 * the next has a cycle of 4, etc. For this reason, we prefer to use the upper
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1709 * bits.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1710 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1711 # define PRN_DEFINE(suffix, var, a, c) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1712 static inline void \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1713 sprn_##suffix(uint32_t seed) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1714 { \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1715 var = seed; \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1716 } \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1717 \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1718 static inline uint32_t \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1719 prn_##suffix(uint32_t lg_range) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1720 { \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1721 uint32_t ret, x; \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1722 \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1723 assert(lg_range > 0); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1724 assert(lg_range <= 32); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1725 \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1726 x = (var * (a)) + (c); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1727 var = x; \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1728 ret = x >> (32 - lg_range); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1729 \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1730 return (ret); \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1731 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1732 # define SPRN(suffix, seed) sprn_##suffix(seed)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1733 # define PRN(suffix, lg_range) prn_##suffix(lg_range)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1734 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1735
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1736 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1737 /* Define the PRNG used for arena assignment. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1738 static __thread uint32_t balance_x;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1739 PRN_DEFINE(balance, balance_x, 1297, 1301)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1740 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1741
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1742 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1743 static int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1744 utrace(const void *addr, size_t len)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1745 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1746 malloc_utrace_t *ut = (malloc_utrace_t *)addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1747
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1748 assert(len == sizeof(malloc_utrace_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1749
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1750 if (ut->p == NULL && ut->s == 0 && ut->r == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1751 malloc_printf("%d x USER malloc_init()\n", getpid());
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1752 else if (ut->p == NULL && ut->r != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1753 malloc_printf("%d x USER %p = malloc(%zu)\n", getpid(), ut->r,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1754 ut->s);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1755 } else if (ut->p != NULL && ut->r != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1756 malloc_printf("%d x USER %p = realloc(%p, %zu)\n", getpid(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1757 ut->r, ut->p, ut->s);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1758 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1759 malloc_printf("%d x USER free(%p)\n", getpid(), ut->p);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1760
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1761 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1762 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1763 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1764
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1765 static inline const char *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1766 _getprogname(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1767 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1768
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1769 return ("<jemalloc>");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1770 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1771
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1772 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1773 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1774 * Print to stderr in such a way as to (hopefully) avoid memory allocation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1775 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1776 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1777 malloc_printf(const char *format, ...)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1778 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1779 #ifndef WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1780 char buf[4096];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1781 va_list ap;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1782
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1783 va_start(ap, format);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1784 vsnprintf(buf, sizeof(buf), format, ap);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1785 va_end(ap);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1786 _malloc_message(buf, "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1787 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1788 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1789 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1790
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1791 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1792
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1793 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1794 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1795 pages_decommit(void *addr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1796 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1797
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1798 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1799 VirtualFree(addr, size, MEM_DECOMMIT);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1800 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1801 if (mmap(addr, size, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1802 0) == MAP_FAILED)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1803 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1804 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1805 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1806
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1807 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1808 pages_commit(void *addr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1809 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1810
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1811 # ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1812 VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1813 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1814 if (mmap(addr, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1815 MAP_ANON, -1, 0) == MAP_FAILED)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1816 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1817 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1818 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1819 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1820
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1821 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1822 base_pages_alloc_mmap(size_t minsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1823 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1824 bool ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1825 size_t csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1826 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1827 size_t pminsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1828 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1829 int pfd;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1830
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1831 assert(minsize != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1832 csize = CHUNK_CEILING(minsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1833 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1834 if (opt_pagefile) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1835 pfd = pagefile_init(csize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1836 if (pfd == -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1837 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1838 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1839 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1840 pfd = -1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1841 base_pages = pages_map(NULL, csize, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1842 if (base_pages == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1843 ret = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1844 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1845 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1846 base_next_addr = base_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1847 base_past_addr = (void *)((uintptr_t)base_pages + csize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1848 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1849 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1850 * Leave enough pages for minsize committed, since otherwise they would
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1851 * have to be immediately recommitted.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1852 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1853 pminsize = PAGE_CEILING(minsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1854 base_next_decommitted = (void *)((uintptr_t)base_pages + pminsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1855 if (pminsize < csize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1856 pages_decommit(base_next_decommitted, csize - pminsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1857 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1858 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1859 base_mapped += csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1860 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1861
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1862 ret = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1863 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1864 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1865 if (pfd != -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1866 pagefile_close(pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1867 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1868 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1869 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1870
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1871 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1872 base_pages_alloc(size_t minsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1873 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1874
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1875 if (base_pages_alloc_mmap(minsize) == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1876 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1877
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1878 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1879 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1880
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1881 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1882 base_alloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1883 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1884 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1885 size_t csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1886
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1887 /* Round size up to nearest multiple of the cacheline size. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1888 csize = CACHELINE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1889
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1890 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1891 /* Make sure there's enough space for the allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1892 if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1893 if (base_pages_alloc(csize)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1894 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1895 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1896 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1897 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1898 /* Allocate. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1899 ret = base_next_addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1900 base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1901 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1902 /* Make sure enough pages are committed for the new allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1903 if ((uintptr_t)base_next_addr > (uintptr_t)base_next_decommitted) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1904 void *pbase_next_addr =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1905 (void *)(PAGE_CEILING((uintptr_t)base_next_addr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1906
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1907 pages_commit(base_next_decommitted, (uintptr_t)pbase_next_addr -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1908 (uintptr_t)base_next_decommitted);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1909 base_next_decommitted = pbase_next_addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1910 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1911 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1912 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1913 VALGRIND_MALLOCLIKE_BLOCK(ret, size, 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1914
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1915 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1916 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1917
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1918 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1919 base_calloc(size_t number, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1920 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1921 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1922
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1923 ret = base_alloc(number * size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1924 #ifdef MALLOC_VALGRIND
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1925 if (ret != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1926 VALGRIND_FREELIKE_BLOCK(ret, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1927 VALGRIND_MALLOCLIKE_BLOCK(ret, size, 0, true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1928 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1929 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1930 memset(ret, 0, number * size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1931
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1932 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1933 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1934
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1935 static extent_node_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1936 base_node_alloc(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1937 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1938 extent_node_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1939
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1940 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1941 if (base_nodes != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1942 ret = base_nodes;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1943 base_nodes = *(extent_node_t **)ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1944 VALGRIND_FREELIKE_BLOCK(ret, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1945 VALGRIND_MALLOCLIKE_BLOCK(ret, sizeof(extent_node_t), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1946 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1947 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1948 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1949 ret = (extent_node_t *)base_alloc(sizeof(extent_node_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1950 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1951
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1952 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1953 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1954
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1955 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1956 base_node_dealloc(extent_node_t *node)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1957 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1958
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1959 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1960 VALGRIND_FREELIKE_BLOCK(node, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1961 VALGRIND_MALLOCLIKE_BLOCK(node, sizeof(extent_node_t *), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1962 *(extent_node_t **)node = base_nodes;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1963 base_nodes = node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1964 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1965 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1966
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1967 static reserve_reg_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1968 base_reserve_reg_alloc(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1969 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1970 reserve_reg_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1971
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1972 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1973 if (base_reserve_regs != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1974 ret = base_reserve_regs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1975 base_reserve_regs = *(reserve_reg_t **)ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1976 VALGRIND_FREELIKE_BLOCK(ret, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1977 VALGRIND_MALLOCLIKE_BLOCK(ret, sizeof(reserve_reg_t), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1978 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1979 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1980 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1981 ret = (reserve_reg_t *)base_alloc(sizeof(reserve_reg_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1982 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1983
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1984 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1985 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1986
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1987 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1988 base_reserve_reg_dealloc(reserve_reg_t *reg)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1989 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1990
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1991 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1992 VALGRIND_FREELIKE_BLOCK(reg, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1993 VALGRIND_MALLOCLIKE_BLOCK(reg, sizeof(reserve_reg_t *), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1994 *(reserve_reg_t **)reg = base_reserve_regs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1995 base_reserve_regs = reg;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1996 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1997 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1998
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
1999 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2000
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2001 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2002 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2003 stats_print(arena_t *arena)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2004 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2005 unsigned i, gap_start;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2006
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2007 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2008 malloc_printf("dirty: %Iu page%s dirty, %I64u sweep%s,"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2009 " %I64u madvise%s, %I64u page%s purged\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2010 arena->ndirty, arena->ndirty == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2011 arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2012 arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2013 arena->stats.purged, arena->stats.purged == 1 ? "" : "s");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2014 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2015 malloc_printf("decommit: %I64u decommit%s, %I64u commit%s,"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2016 " %I64u page%s decommitted\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2017 arena->stats.ndecommit, (arena->stats.ndecommit == 1) ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2018 arena->stats.ncommit, (arena->stats.ncommit == 1) ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2019 arena->stats.decommitted,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2020 (arena->stats.decommitted == 1) ? "" : "s");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2021 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2022
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2023 malloc_printf(" allocated nmalloc ndalloc\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2024 malloc_printf("small: %12Iu %12I64u %12I64u\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2025 arena->stats.allocated_small, arena->stats.nmalloc_small,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2026 arena->stats.ndalloc_small);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2027 malloc_printf("large: %12Iu %12I64u %12I64u\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2028 arena->stats.allocated_large, arena->stats.nmalloc_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2029 arena->stats.ndalloc_large);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2030 malloc_printf("total: %12Iu %12I64u %12I64u\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2031 arena->stats.allocated_small + arena->stats.allocated_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2032 arena->stats.nmalloc_small + arena->stats.nmalloc_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2033 arena->stats.ndalloc_small + arena->stats.ndalloc_large);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2034 malloc_printf("mapped: %12Iu\n", arena->stats.mapped);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2035 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2036 malloc_printf("dirty: %zu page%s dirty, %llu sweep%s,"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2037 " %llu madvise%s, %llu page%s purged\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2038 arena->ndirty, arena->ndirty == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2039 arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2040 arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2041 arena->stats.purged, arena->stats.purged == 1 ? "" : "s");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2042 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2043 malloc_printf("decommit: %llu decommit%s, %llu commit%s,"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2044 " %llu page%s decommitted\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2045 arena->stats.ndecommit, (arena->stats.ndecommit == 1) ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2046 arena->stats.ncommit, (arena->stats.ncommit == 1) ? "" : "s",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2047 arena->stats.decommitted,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2048 (arena->stats.decommitted == 1) ? "" : "s");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2049 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2050
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2051 malloc_printf(" allocated nmalloc ndalloc\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2052 malloc_printf("small: %12zu %12llu %12llu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2053 arena->stats.allocated_small, arena->stats.nmalloc_small,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2054 arena->stats.ndalloc_small);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2055 malloc_printf("large: %12zu %12llu %12llu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2056 arena->stats.allocated_large, arena->stats.nmalloc_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2057 arena->stats.ndalloc_large);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2058 malloc_printf("total: %12zu %12llu %12llu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2059 arena->stats.allocated_small + arena->stats.allocated_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2060 arena->stats.nmalloc_small + arena->stats.nmalloc_large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2061 arena->stats.ndalloc_small + arena->stats.ndalloc_large);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2062 malloc_printf("mapped: %12zu\n", arena->stats.mapped);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2063 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2064 malloc_printf("bins: bin size regs pgs requests newruns"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2065 " reruns maxruns curruns\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2066 for (i = 0, gap_start = UINT_MAX; i < ntbins + nqbins + nsbins; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2067 if (arena->bins[i].stats.nrequests == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2068 if (gap_start == UINT_MAX)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2069 gap_start = i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2070 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2071 if (gap_start != UINT_MAX) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2072 if (i > gap_start + 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2073 /* Gap of more than one size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2074 malloc_printf("[%u..%u]\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2075 gap_start, i - 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2076 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2077 /* Gap of one size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2078 malloc_printf("[%u]\n", gap_start);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2079 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2080 gap_start = UINT_MAX;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2081 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2082 malloc_printf(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2083 #if defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2084 "%13u %1s %4u %4u %3u %9I64u %9I64u"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2085 " %9I64u %7u %7u\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2086 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2087 "%13u %1s %4u %4u %3u %9llu %9llu"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2088 " %9llu %7lu %7lu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2089 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2090 i,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2091 i < ntbins ? "T" : i < ntbins + nqbins ? "Q" : "S",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2092 arena->bins[i].reg_size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2093 arena->bins[i].nregs,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2094 arena->bins[i].run_size >> pagesize_2pow,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2095 arena->bins[i].stats.nrequests,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2096 arena->bins[i].stats.nruns,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2097 arena->bins[i].stats.reruns,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2098 arena->bins[i].stats.highruns,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2099 arena->bins[i].stats.curruns);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2100 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2101 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2102 if (gap_start != UINT_MAX) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2103 if (i > gap_start + 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2104 /* Gap of more than one size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2105 malloc_printf("[%u..%u]\n", gap_start, i - 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2106 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2107 /* Gap of one size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2108 malloc_printf("[%u]\n", gap_start);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2109 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2110 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2111 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2112 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2113
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2114 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2115 * End Utility functions/macros.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2116 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2117 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2118 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2119 * Begin extent tree code.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2120 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2121
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2122 static inline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2123 extent_szad_comp(extent_node_t *a, extent_node_t *b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2124 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2125 int ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2126 size_t a_size = a->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2127 size_t b_size = b->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2128
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2129 ret = (a_size > b_size) - (a_size < b_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2130 if (ret == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2131 uintptr_t a_addr = (uintptr_t)a->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2132 uintptr_t b_addr = (uintptr_t)b->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2133
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2134 ret = (a_addr > b_addr) - (a_addr < b_addr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2135 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2136
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2137 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2138 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2139
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2140 /* Wrap red-black tree macros in functions. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2141 rb_wrap(static, extent_tree_szad_, extent_tree_t, extent_node_t,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2142 link_szad, extent_szad_comp)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2143
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2144 static inline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2145 extent_ad_comp(extent_node_t *a, extent_node_t *b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2146 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2147 uintptr_t a_addr = (uintptr_t)a->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2148 uintptr_t b_addr = (uintptr_t)b->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2149
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2150 return ((a_addr > b_addr) - (a_addr < b_addr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2151 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2152
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2153 /* Wrap red-black tree macros in functions. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2154 rb_wrap(static, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2155 extent_ad_comp)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2156
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2157 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2158 * End extent tree code.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2159 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2160 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2161 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2162 * Begin chunk management functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2163 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2164
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2165 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2166 #ifdef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2167 #define ALIGN_ADDR2OFFSET(al, ad) \
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2168 ((uintptr_t)ad & (al - 1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2169 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2170 pages_map_align(size_t size, int pfd, size_t alignment)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2171 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2172
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2173 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2174 int offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2175 if (size % alignment)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2176 size += (alignment - (size % alignment));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2177 assert(size >= alignment);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2178 ret = pages_map(NULL, size, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2179 offset = ALIGN_ADDR2OFFSET(alignment, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2180 if (offset) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2181 /* try to over allocate by the ammount we're offset */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2182 void *tmp;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2183 pages_unmap(ret, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2184 tmp = VirtualAlloc(NULL, size + alignment - offset,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2185 MEM_RESERVE, PAGE_NOACCESS);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2186 if (offset == ALIGN_ADDR2OFFSET(alignment, tmp))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2187 ret = VirtualAlloc((void*)((intptr_t)tmp + alignment
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2188 - offset), size, MEM_COMMIT,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2189 PAGE_READWRITE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2190 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2191 VirtualFree(tmp, 0, MEM_RELEASE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2192 offset = ALIGN_ADDR2OFFSET(alignment, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2193
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2194
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2195 if (offset) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2196 /* over allocate to ensure we have an aligned region */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2197 ret = VirtualAlloc(NULL, size + alignment, MEM_RESERVE,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2198 PAGE_NOACCESS);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2199 offset = ALIGN_ADDR2OFFSET(alignment, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2200 ret = VirtualAlloc((void*)((intptr_t)ret +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2201 alignment - offset),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2202 size, MEM_COMMIT, PAGE_READWRITE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2203 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2204 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2205 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2206 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2207 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2208
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2209 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2210 pages_map(void *addr, size_t size, int pfd)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2211 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2212 void *ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2213 #if defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2214 void *va_ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2215 assert(addr == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2216 va_ret = VirtualAlloc(addr, size, MEM_RESERVE, PAGE_NOACCESS);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2217 if (va_ret)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2218 ret = VirtualAlloc(va_ret, size, MEM_COMMIT, PAGE_READWRITE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2219 assert(va_ret == ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2220 #elif defined(MOZ_MEMORY_WINDOWS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2221 ret = VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2222 PAGE_READWRITE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2223 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2224 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2225 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2226
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2227 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2228 pages_unmap(void *addr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2229 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2230 if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2231 #ifdef MOZ_MEMORY_WINCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2232 if (GetLastError() == ERROR_INVALID_PARAMETER) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2233 MEMORY_BASIC_INFORMATION info;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2234 VirtualQuery(addr, &info, sizeof(info));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2235 if (VirtualFree(info.AllocationBase, 0, MEM_RELEASE))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2236 return;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2237 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2238 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2239 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2240 ": (malloc) Error in VirtualFree()\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2241 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2242 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2243 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2244 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2245 #elif (defined(MOZ_MEMORY_DARWIN))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2246 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2247 pages_map(void *addr, size_t size, int pfd)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2248 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2249 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2250 kern_return_t err;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2251 int flags;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2252
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2253 if (addr != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2254 ret = addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2255 flags = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2256 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2257 flags = VM_FLAGS_ANYWHERE;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2258
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2259 err = vm_allocate((vm_map_t)mach_task_self(), (vm_address_t *)&ret,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2260 (vm_size_t)size, flags);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2261 if (err != KERN_SUCCESS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2262 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2263
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2264 assert(ret == NULL || (addr == NULL && ret != addr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2265 || (addr != NULL && ret == addr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2266 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2267 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2268
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2269 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2270 pages_unmap(void *addr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2271 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2272 kern_return_t err;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2273
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2274 err = vm_deallocate((vm_map_t)mach_task_self(), (vm_address_t)addr,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2275 (vm_size_t)size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2276 if (err != KERN_SUCCESS) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2277 malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2278 ": (malloc) Error in vm_deallocate(): ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2279 mach_error_string(err), "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2280 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2281 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2282 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2283 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2284
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2285 #define VM_COPY_MIN (pagesize << 5)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2286 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2287 pages_copy(void *dest, const void *src, size_t n)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2288 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2289
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2290 assert((void *)((uintptr_t)dest & ~pagesize_mask) == dest);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2291 assert(n >= VM_COPY_MIN);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2292 assert((void *)((uintptr_t)src & ~pagesize_mask) == src);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2293
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2294 vm_copy(mach_task_self(), (vm_address_t)src, (vm_size_t)n,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2295 (vm_address_t)dest);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2296 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2297 #else /* MOZ_MEMORY_DARWIN */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2298 #ifdef JEMALLOC_USES_MAP_ALIGN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2299 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2300 pages_map_align(size_t size, int pfd, size_t alignment)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2301 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2302 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2303
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2304 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2305 * We don't use MAP_FIXED here, because it can cause the *replacement*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2306 * of existing mappings, and we only want to create new mappings.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2307 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2308 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2309 if (pfd != -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2310 ret = mmap((void *)alignment, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2311 MAP_NOSYNC | MAP_ALIGN, pfd, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2312 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2313 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2314 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2315 ret = mmap((void *)alignment, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2316 MAP_NOSYNC | MAP_ALIGN | MAP_ANON, -1, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2317 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2318 assert(ret != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2319
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2320 if (ret == MAP_FAILED)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2321 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2322 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2323 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2324 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2325
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2326 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2327 pages_map(void *addr, size_t size, int pfd)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2328 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2329 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2330
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2331 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2332 * We don't use MAP_FIXED here, because it can cause the *replacement*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2333 * of existing mappings, and we only want to create new mappings.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2334 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2335 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2336 if (pfd != -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2337 ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2338 MAP_NOSYNC, pfd, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2339 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2340 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2341 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2342 ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2343 MAP_ANON, -1, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2344 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2345 assert(ret != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2346
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2347 if (ret == MAP_FAILED)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2348 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2349 else if (addr != NULL && ret != addr) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2350 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2351 * We succeeded in mapping memory, but not in the right place.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2352 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2353 if (munmap(ret, size) == -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2354 char buf[STRERROR_BUF];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2355
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2356 strerror_r(errno, buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2357 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2358 ": (malloc) Error in munmap(): ", buf, "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2359 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2360 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2361 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2362 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2363 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2364
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2365 assert(ret == NULL || (addr == NULL && ret != addr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2366 || (addr != NULL && ret == addr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2367 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2368 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2369
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2370 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2371 pages_unmap(void *addr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2372 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2373
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2374 if (munmap(addr, size) == -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2375 char buf[STRERROR_BUF];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2376
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2377 strerror_r(errno, buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2378 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2379 ": (malloc) Error in munmap(): ", buf, "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2380 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2381 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2382 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2383 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2384 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2385
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2386 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2387 static inline malloc_rtree_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2388 malloc_rtree_new(unsigned bits)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2389 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2390 malloc_rtree_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2391 unsigned bits_per_level, height, i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2392
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2393 bits_per_level = ffs(pow2_ceil((MALLOC_RTREE_NODESIZE /
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2394 sizeof(void *)))) - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2395 height = bits / bits_per_level;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2396 if (height * bits_per_level != bits)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2397 height++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2398 assert(height * bits_per_level >= bits);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2399
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2400 ret = (malloc_rtree_t*)base_calloc(1, sizeof(malloc_rtree_t) + (sizeof(unsigned) *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2401 (height - 1)));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2402 if (ret == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2403 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2404
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2405 malloc_spin_init(&ret->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2406 ret->height = height;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2407 if (bits_per_level * height > bits)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2408 ret->level2bits[0] = bits % bits_per_level;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2409 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2410 ret->level2bits[0] = bits_per_level;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2411 for (i = 1; i < height; i++)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2412 ret->level2bits[i] = bits_per_level;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2413
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2414 ret->root = (void**)base_calloc(1, sizeof(void *) << ret->level2bits[0]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2415 if (ret->root == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2416 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2417 * We leak the rtree here, since there's no generic base
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2418 * deallocation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2419 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2420 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2421 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2422
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2423 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2424 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2425
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2426 /* The least significant bits of the key are ignored. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2427 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2428 malloc_rtree_get(malloc_rtree_t *rtree, uintptr_t key)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2429 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2430 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2431 uintptr_t subkey;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2432 unsigned i, lshift, height, bits;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2433 void **node, **child;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2434
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2435 malloc_spin_lock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2436 for (i = lshift = 0, height = rtree->height, node = rtree->root;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2437 i < height - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2438 i++, lshift += bits, node = child) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2439 bits = rtree->level2bits[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2440 subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2441 child = (void**)node[subkey];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2442 if (child == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2443 malloc_spin_unlock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2444 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2445 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2446 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2447
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2448 /* node is a leaf, so it contains values rather than node pointers. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2449 bits = rtree->level2bits[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2450 subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2451 ret = node[subkey];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2452 malloc_spin_unlock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2453
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2454 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2455 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2456
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2457 static inline bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2458 malloc_rtree_set(malloc_rtree_t *rtree, uintptr_t key, void *val)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2459 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2460 uintptr_t subkey;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2461 unsigned i, lshift, height, bits;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2462 void **node, **child;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2463
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2464 malloc_spin_lock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2465 for (i = lshift = 0, height = rtree->height, node = rtree->root;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2466 i < height - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2467 i++, lshift += bits, node = child) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2468 bits = rtree->level2bits[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2469 subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2470 child = (void**)node[subkey];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2471 if (child == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2472 child = (void**)base_calloc(1, sizeof(void *) <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2473 rtree->level2bits[i+1]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2474 if (child == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2475 malloc_spin_unlock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2476 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2477 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2478 node[subkey] = child;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2479 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2480 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2481
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2482 /* node is a leaf, so it contains values rather than node pointers. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2483 bits = rtree->level2bits[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2484 subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2485 node[subkey] = val;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2486 malloc_spin_unlock(&rtree->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2487
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2488 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2489 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2490 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2491
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2492 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2493 chunk_alloc_mmap(size_t size, bool pagefile)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2494 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2495 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2496 #ifndef JEMALLOC_USES_MAP_ALIGN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2497 size_t offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2498 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2499 int pfd;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2500
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2501 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2502 if (opt_pagefile && pagefile) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2503 pfd = pagefile_init(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2504 if (pfd == -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2505 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2506 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2507 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2508 pfd = -1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2509
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2510 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2511 * Windows requires that there be a 1:1 mapping between VM
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2512 * allocation/deallocation operations. Therefore, take care here to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2513 * acquire the final result via one mapping operation. This means
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2514 * unmapping any preliminary result that is not correctly aligned.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2515 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2516 * The MALLOC_PAGEFILE code also benefits from this mapping algorithm,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2517 * since it reduces the number of page files.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2518 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2519
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2520 #ifdef JEMALLOC_USES_MAP_ALIGN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2521 ret = pages_map_align(size, pfd, chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2522 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2523 ret = pages_map(NULL, size, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2524 if (ret == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2525 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2526
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2527 offset = CHUNK_ADDR2OFFSET(ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2528 if (offset != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2529 /* Deallocate, then try to allocate at (ret + size - offset). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2530 pages_unmap(ret, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2531 ret = pages_map((void *)((uintptr_t)ret + size - offset), size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2532 pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2533 while (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2534 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2535 * Over-allocate in order to map a memory region that
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2536 * is definitely large enough.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2537 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2538 ret = pages_map(NULL, size + chunksize, -1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2539 if (ret == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2540 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2541 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2542 * Deallocate, then allocate the correct size, within
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2543 * the over-sized mapping.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2544 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2545 offset = CHUNK_ADDR2OFFSET(ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2546 pages_unmap(ret, size + chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2547 if (offset == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2548 ret = pages_map(ret, size, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2549 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2550 ret = pages_map((void *)((uintptr_t)ret +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2551 chunksize - offset), size, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2552 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2553 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2554 * Failure here indicates a race with another thread, so
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2555 * try again.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2556 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2557 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2558 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2559 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2560 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2561 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2562 if (pfd != -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2563 pagefile_close(pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2564 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2565 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2566 if (ret != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2567 stats_chunks.nchunks += (size / chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2568 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2569 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2570 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2571
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2572 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2573 static int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2574 pagefile_init(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2575 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2576 int ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2577 size_t i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2578 char pagefile_path[PATH_MAX];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2579 char zbuf[MALLOC_PAGEFILE_WRITE_SIZE];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2580
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2581 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2582 * Create a temporary file, then immediately unlink it so that it will
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2583 * not persist.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2584 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2585 strcpy(pagefile_path, pagefile_templ);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2586 ret = mkstemp(pagefile_path);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2587 if (ret == -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2588 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2589 if (unlink(pagefile_path)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2590 char buf[STRERROR_BUF];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2591
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2592 strerror_r(errno, buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2593 _malloc_message(_getprogname(), ": (malloc) Error in unlink(\"",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2594 pagefile_path, "\"):");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2595 _malloc_message(buf, "\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2596 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2597 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2598 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2599
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2600 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2601 * Write sequential zeroes to the file in order to assure that disk
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2602 * space is committed, with minimal fragmentation. It would be
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2603 * sufficient to write one zero per disk block, but that potentially
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2604 * results in more system calls, for no real gain.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2605 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2606 memset(zbuf, 0, sizeof(zbuf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2607 for (i = 0; i < size; i += sizeof(zbuf)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2608 if (write(ret, zbuf, sizeof(zbuf)) != sizeof(zbuf)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2609 if (errno != ENOSPC) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2610 char buf[STRERROR_BUF];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2611
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2612 strerror_r(errno, buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2613 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2614 ": (malloc) Error in write(): ", buf, "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2615 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2616 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2617 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2618 pagefile_close(ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2619 return (-1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2620 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2621 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2622
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2623 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2624 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2625
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2626 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2627 pagefile_close(int pfd)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2628 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2629
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2630 if (close(pfd)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2631 char buf[STRERROR_BUF];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2632
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2633 strerror_r(errno, buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2634 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2635 ": (malloc) Error in close(): ", buf, "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2636 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2637 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2638 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2639 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2640 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2641
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2642 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2643 chunk_recycle_reserve(size_t size, bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2644 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2645 extent_node_t *node, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2646
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2647 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2648 if (size != chunksize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2649 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2650 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2651
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2652 key.addr = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2653 key.size = size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2654 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2655 node = extent_tree_szad_nsearch(&reserve_chunks_szad, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2656 if (node != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2657 void *ret = node->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2658
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2659 /* Remove node from the tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2660 extent_tree_szad_remove(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2661 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2662 if (node->size == size) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2663 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2664 assert(node->size == size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2665 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2666 extent_tree_ad_remove(&reserve_chunks_ad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2667 base_node_dealloc(node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2668 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2669 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2670 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2671 * Insert the remainder of node's address range as a
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2672 * smaller chunk. Its position within reserve_chunks_ad
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2673 * does not change.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2674 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2675 assert(node->size > size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2676 node->addr = (void *)((uintptr_t)node->addr + size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2677 node->size -= size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2678 extent_tree_szad_insert(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2679 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2680 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2681 reserve_cur -= size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2682 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2683 * Try to replenish the reserve if this allocation depleted it.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2684 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2685 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2686 if (reserve_cur < reserve_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2687 size_t diff = reserve_min - reserve_cur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2688 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2689 while (reserve_cur < reserve_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2690 # define diff chunksize
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2691 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2692 void *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2693
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2694 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2695 chunk = chunk_alloc_mmap(diff, true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2696 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2697 if (chunk == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2698 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2699
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2700 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2701 seq = reserve_notify(RESERVE_CND_LOW,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2702 size, seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2703 if (seq == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2704 goto MALLOC_OUT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2705 } while (reserve_cur < reserve_min);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2706 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2707 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2708
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2709 node = chunk_dealloc_reserve(chunk, diff);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2710 if (node == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2711 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2712
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2713 pages_unmap(chunk, diff);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2714 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2715 seq = reserve_notify(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2716 RESERVE_CND_LOW, size, seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2717 if (seq == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2718 goto MALLOC_OUT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2719 } while (reserve_cur < reserve_min);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2720 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2721 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2722 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2723 MALLOC_OUT:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2724 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2725
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2726 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2727 pages_commit(ret, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2728 # undef diff
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2729 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2730 if (zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2731 memset(ret, 0, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2732 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2733 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2734 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2735 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2736
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2737 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2738 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2739
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2740 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2741 chunk_alloc(size_t size, bool zero, bool pagefile)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2742 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2743 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2744
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2745 assert(size != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2746 assert((size & chunksize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2747
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2748 ret = chunk_recycle_reserve(size, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2749 if (ret != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2750 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2751
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2752 ret = chunk_alloc_mmap(size, pagefile);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2753 if (ret != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2754 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2755 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2756
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2757 /* All strategies for allocation failed. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2758 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2759 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2760 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2761 if (ret != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2762 stats_chunks.curchunks += (size / chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2763 if (stats_chunks.curchunks > stats_chunks.highchunks)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2764 stats_chunks.highchunks = stats_chunks.curchunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2765 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2766
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2767 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2768 if (ret != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2769 if (malloc_rtree_set(chunk_rtree, (uintptr_t)ret, ret)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2770 chunk_dealloc(ret, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2771 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2772 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2773 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2774 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2775
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2776 assert(CHUNK_ADDR2BASE(ret) == ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2777 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2778 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2779
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2780 static extent_node_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2781 chunk_dealloc_reserve(void *chunk, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2782 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2783 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2784
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2785 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2786 if (size != chunksize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2787 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2788 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2789 extent_node_t *prev, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2790
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2791 key.addr = (void *)((uintptr_t)chunk + size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2792 node = extent_tree_ad_nsearch(&reserve_chunks_ad, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2793 /* Try to coalesce forward. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2794 if (node != NULL && node->addr == key.addr) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2795 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2796 * Coalesce chunk with the following address range. This does
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2797 * not change the position within reserve_chunks_ad, so only
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2798 * remove/insert from/into reserve_chunks_szad.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2799 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2800 extent_tree_szad_remove(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2801 node->addr = chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2802 node->size += size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2803 extent_tree_szad_insert(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2804 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2805 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2806 /* Coalescing forward failed, so insert a new node. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2807 node = base_node_alloc();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2808 if (node == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2809 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2810 node->addr = chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2811 node->size = size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2812 extent_tree_ad_insert(&reserve_chunks_ad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2813 extent_tree_szad_insert(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2814 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2815 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2816
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2817 /* Try to coalesce backward. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2818 prev = extent_tree_ad_prev(&reserve_chunks_ad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2819 if (prev != NULL && (void *)((uintptr_t)prev->addr + prev->size) ==
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2820 chunk) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2821 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2822 * Coalesce chunk with the previous address range. This does
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2823 * not change the position within reserve_chunks_ad, so only
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2824 * remove/insert node from/into reserve_chunks_szad.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2825 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2826 extent_tree_szad_remove(&reserve_chunks_szad, prev);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2827 extent_tree_ad_remove(&reserve_chunks_ad, prev);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2828
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2829 extent_tree_szad_remove(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2830 node->addr = prev->addr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2831 node->size += prev->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2832 extent_tree_szad_insert(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2833
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2834 base_node_dealloc(prev);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2835 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2836 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2837
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2838 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2839 pages_decommit(chunk, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2840 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2841 madvise(chunk, size, MADV_FREE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2842 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2843
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2844 reserve_cur += size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2845 if (reserve_cur > reserve_max)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2846 reserve_shrink();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2847
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2848 return (node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2849 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2850
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2851 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2852 chunk_dealloc_mmap(void *chunk, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2853 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2854
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2855 pages_unmap(chunk, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2856 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2857
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2858 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2859 chunk_dealloc(void *chunk, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2860 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2861 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2862
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2863 assert(chunk != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2864 assert(CHUNK_ADDR2BASE(chunk) == chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2865 assert(size != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2866 assert((size & chunksize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2867
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2868 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2869 stats_chunks.curchunks -= (size / chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2870 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2871 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2872 malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2873 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2874
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2875 /* Try to merge chunk into the reserve. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2876 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2877 node = chunk_dealloc_reserve(chunk, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2878 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2879 if (node == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2880 chunk_dealloc_mmap(chunk, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2881 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2882
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2883 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2884 * End chunk management functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2885 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2886 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2887 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2888 * Begin arena.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2889 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2890
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2891 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2892 * Choose an arena based on a per-thread value (fast-path code, calls slow-path
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2893 * code if necessary).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2894 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2895 static inline arena_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2896 choose_arena(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2897 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2898 arena_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2899
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2900 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2901 * We can only use TLS if this is a PIC library, since for the static
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2902 * library version, libc's malloc is used by TLS allocation, which
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2903 * introduces a bootstrapping issue.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2904 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2905 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2906 if (__isthreaded == false) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2907 /* Avoid the overhead of TLS for single-threaded operation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2908 return (arenas[0]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2909 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2910
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2911 # ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2912 ret = (arena_t*)TlsGetValue(tlsIndex);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2913 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2914 ret = arenas_map;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2915 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2916
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2917 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2918 ret = choose_arena_hard();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2919 assert(ret != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2920 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2921 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2922 if (__isthreaded && narenas > 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2923 unsigned long ind;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2924
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2925 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2926 * Hash _pthread_self() to one of the arenas. There is a prime
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2927 * number of arenas, so this has a reasonable chance of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2928 * working. Even so, the hashing can be easily thwarted by
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2929 * inconvenient _pthread_self() values. Without specific
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2930 * knowledge of how _pthread_self() calculates values, we can't
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2931 * easily do much better than this.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2932 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2933 ind = (unsigned long) _pthread_self() % narenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2934
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2935 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2936 * Optimistially assume that arenas[ind] has been initialized.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2937 * At worst, we find out that some other thread has already
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2938 * done so, after acquiring the lock in preparation. Note that
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2939 * this lazy locking also has the effect of lazily forcing
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2940 * cache coherency; without the lock acquisition, there's no
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2941 * guarantee that modification of arenas[ind] by another thread
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2942 * would be seen on this CPU for an arbitrary amount of time.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2943 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2944 * In general, this approach to modifying a synchronized value
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2945 * isn't a good idea, but in this case we only ever modify the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2946 * value once, so things work out well.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2947 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2948 ret = arenas[ind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2949 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2950 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2951 * Avoid races with another thread that may have already
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2952 * initialized arenas[ind].
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2953 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2954 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2955 if (arenas[ind] == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2956 ret = arenas_extend((unsigned)ind);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2957 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2958 ret = arenas[ind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2959 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2960 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2961 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2962 ret = arenas[0];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2963 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2964
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2965 assert(ret != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2966 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2967 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2968
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2969 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2970 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2971 * Choose an arena based on a per-thread value (slow-path code only, called
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2972 * only by choose_arena()).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2973 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2974 static arena_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2975 choose_arena_hard(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2976 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2977 arena_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2978
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2979 assert(__isthreaded);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2980
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2981 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2982 /* Seed the PRNG used for arena load balancing. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2983 SPRN(balance, (uint32_t)(uintptr_t)(_pthread_self()));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2984 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2985
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2986 if (narenas > 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2987 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2988 unsigned ind;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2989
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2990 ind = PRN(balance, narenas_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2991 if ((ret = arenas[ind]) == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2992 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2993 if ((ret = arenas[ind]) == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2994 ret = arenas_extend(ind);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2995 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2996 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2997 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2998 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
2999 if ((ret = arenas[next_arena]) == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3000 ret = arenas_extend(next_arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3001 next_arena = (next_arena + 1) % narenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3002 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3003 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3004 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3005 ret = arenas[0];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3006
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3007 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3008 TlsSetValue(tlsIndex, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3009 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3010 arenas_map = ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3011 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3012
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3013 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3014 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3015 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3016
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3017 static inline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3018 arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3019 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3020 uintptr_t a_chunk = (uintptr_t)a;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3021 uintptr_t b_chunk = (uintptr_t)b;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3022
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3023 assert(a != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3024 assert(b != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3025
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3026 return ((a_chunk > b_chunk) - (a_chunk < b_chunk));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3027 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3028
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3029 /* Wrap red-black tree macros in functions. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3030 rb_wrap(static, arena_chunk_tree_dirty_, arena_chunk_tree_t,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3031 arena_chunk_t, link_dirty, arena_chunk_comp)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3032
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3033 static inline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3034 arena_run_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3035 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3036 uintptr_t a_mapelm = (uintptr_t)a;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3037 uintptr_t b_mapelm = (uintptr_t)b;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3038
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3039 assert(a != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3040 assert(b != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3041
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3042 return ((a_mapelm > b_mapelm) - (a_mapelm < b_mapelm));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3043 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3044
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3045 /* Wrap red-black tree macros in functions. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3046 rb_wrap(static, arena_run_tree_, arena_run_tree_t, arena_chunk_map_t, link,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3047 arena_run_comp)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3048
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3049 static inline int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3050 arena_avail_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3051 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3052 int ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3053 size_t a_size = a->bits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3054 size_t b_size = b->bits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3055
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3056 ret = (a_size > b_size) - (a_size < b_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3057 if (ret == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3058 uintptr_t a_mapelm, b_mapelm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3059
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3060 if ((a->bits & CHUNK_MAP_KEY) == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3061 a_mapelm = (uintptr_t)a;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3062 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3063 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3064 * Treat keys as though they are lower than anything
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3065 * else.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3066 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3067 a_mapelm = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3068 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3069 b_mapelm = (uintptr_t)b;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3070
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3071 ret = (a_mapelm > b_mapelm) - (a_mapelm < b_mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3072 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3073
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3074 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3075 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3076
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3077 /* Wrap red-black tree macros in functions. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3078 rb_wrap(static, arena_avail_tree_, arena_avail_tree_t, arena_chunk_map_t, link,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3079 arena_avail_comp)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3080
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3081 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3082 arena_run_reg_alloc(arena_run_t *run, arena_bin_t *bin)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3083 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3084 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3085 unsigned i, mask, bit, regind;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3086
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3087 assert(run->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3088 assert(run->regs_minelm < bin->regs_mask_nelms);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3089
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3090 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3091 * Move the first check outside the loop, so that run->regs_minelm can
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3092 * be updated unconditionally, without the possibility of updating it
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3093 * multiple times.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3094 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3095 i = run->regs_minelm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3096 mask = run->regs_mask[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3097 if (mask != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3098 /* Usable allocation found. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3099 bit = ffs((int)mask) - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3100
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3101 regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3102 assert(regind < bin->nregs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3103 ret = (void *)(((uintptr_t)run) + bin->reg0_offset
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3104 + (bin->reg_size * regind));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3105
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3106 /* Clear bit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3107 mask ^= (1U << bit);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3108 run->regs_mask[i] = mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3109
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3110 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3111 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3112
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3113 for (i++; i < bin->regs_mask_nelms; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3114 mask = run->regs_mask[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3115 if (mask != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3116 /* Usable allocation found. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3117 bit = ffs((int)mask) - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3118
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3119 regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3120 assert(regind < bin->nregs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3121 ret = (void *)(((uintptr_t)run) + bin->reg0_offset
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3122 + (bin->reg_size * regind));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3123
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3124 /* Clear bit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3125 mask ^= (1U << bit);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3126 run->regs_mask[i] = mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3127
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3128 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3129 * Make a note that nothing before this element
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3130 * contains a free region.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3131 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3132 run->regs_minelm = i; /* Low payoff: + (mask == 0); */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3133
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3134 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3135 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3136 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3137 /* Not reached. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3138 assert(0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3139 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3140 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3141
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3142 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3143 arena_run_reg_dalloc(arena_run_t *run, arena_bin_t *bin, void *ptr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3144 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3145 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3146 * To divide by a number D that is not a power of two we multiply
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3147 * by (2^21 / D) and then right shift by 21 positions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3148 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3149 * X / D
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3150 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3151 * becomes
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3152 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3153 * (X * size_invs[(D >> QUANTUM_2POW_MIN) - 3]) >> SIZE_INV_SHIFT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3154 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3155 #define SIZE_INV_SHIFT 21
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3156 #define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s << QUANTUM_2POW_MIN)) + 1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3157 static const unsigned size_invs[] = {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3158 SIZE_INV(3),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3159 SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3160 SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3161 SIZE_INV(12),SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3162 SIZE_INV(16),SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3163 SIZE_INV(20),SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3164 SIZE_INV(24),SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3165 SIZE_INV(28),SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3166 #if (QUANTUM_2POW_MIN < 4)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3167 ,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3168 SIZE_INV(32), SIZE_INV(33), SIZE_INV(34), SIZE_INV(35),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3169 SIZE_INV(36), SIZE_INV(37), SIZE_INV(38), SIZE_INV(39),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3170 SIZE_INV(40), SIZE_INV(41), SIZE_INV(42), SIZE_INV(43),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3171 SIZE_INV(44), SIZE_INV(45), SIZE_INV(46), SIZE_INV(47),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3172 SIZE_INV(48), SIZE_INV(49), SIZE_INV(50), SIZE_INV(51),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3173 SIZE_INV(52), SIZE_INV(53), SIZE_INV(54), SIZE_INV(55),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3174 SIZE_INV(56), SIZE_INV(57), SIZE_INV(58), SIZE_INV(59),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3175 SIZE_INV(60), SIZE_INV(61), SIZE_INV(62), SIZE_INV(63)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3176 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3177 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3178 unsigned diff, regind, elm, bit;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3179
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3180 assert(run->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3181 assert(((sizeof(size_invs)) / sizeof(unsigned)) + 3
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3182 >= (SMALL_MAX_DEFAULT >> QUANTUM_2POW_MIN));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3183
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3184 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3185 * Avoid doing division with a variable divisor if possible. Using
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3186 * actual division here can reduce allocator throughput by over 20%!
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3187 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3188 diff = (unsigned)((uintptr_t)ptr - (uintptr_t)run - bin->reg0_offset);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3189 if ((size & (size - 1)) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3190 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3191 * log2_table allows fast division of a power of two in the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3192 * [1..128] range.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3193 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3194 * (x / divisor) becomes (x >> log2_table[divisor - 1]).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3195 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3196 static const unsigned char log2_table[] = {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3197 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3205 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3206
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3207 if (size <= 128)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3208 regind = (diff >> log2_table[size - 1]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3209 else if (size <= 32768)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3210 regind = diff >> (8 + log2_table[(size >> 8) - 1]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3211 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3212 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3213 * The run size is too large for us to use the lookup
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3214 * table. Use real division.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3215 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3216 regind = diff / size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3217 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3218 } else if (size <= ((sizeof(size_invs) / sizeof(unsigned))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3219 << QUANTUM_2POW_MIN) + 2) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3220 regind = size_invs[(size >> QUANTUM_2POW_MIN) - 3] * diff;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3221 regind >>= SIZE_INV_SHIFT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3222 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3223 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3224 * size_invs isn't large enough to handle this size class, so
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3225 * calculate regind using actual division. This only happens
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3226 * if the user increases small_max via the 'S' runtime
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3227 * configuration option.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3228 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3229 regind = diff / size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3230 };
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3231 assert(diff == regind * size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3232 assert(regind < bin->nregs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3233
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3234 elm = regind >> (SIZEOF_INT_2POW + 3);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3235 if (elm < run->regs_minelm)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3236 run->regs_minelm = elm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3237 bit = regind - (elm << (SIZEOF_INT_2POW + 3));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3238 assert((run->regs_mask[elm] & (1U << bit)) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3239 run->regs_mask[elm] |= (1U << bit);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3240 #undef SIZE_INV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3241 #undef SIZE_INV_SHIFT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3242 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3243
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3244 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3245 arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3246 bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3247 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3248 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3249 size_t old_ndirty, run_ind, total_pages, need_pages, rem_pages, i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3250
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3251 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3252 old_ndirty = chunk->ndirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3253 run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3254 >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3255 total_pages = (chunk->map[run_ind].bits & ~pagesize_mask) >>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3256 pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3257 need_pages = (size >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3258 assert(need_pages > 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3259 assert(need_pages <= total_pages);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3260 rem_pages = total_pages - need_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3261
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3262 arena_avail_tree_remove(&arena->runs_avail, &chunk->map[run_ind]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3263
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3264 /* Keep track of trailing unused pages for later use. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3265 if (rem_pages > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3266 chunk->map[run_ind+need_pages].bits = (rem_pages <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3267 pagesize_2pow) | (chunk->map[run_ind+need_pages].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3268 pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3269 chunk->map[run_ind+total_pages-1].bits = (rem_pages <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3270 pagesize_2pow) | (chunk->map[run_ind+total_pages-1].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3271 pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3272 arena_avail_tree_insert(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3273 &chunk->map[run_ind+need_pages]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3274 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3275
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3276 for (i = 0; i < need_pages; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3277 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3278 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3279 * Commit decommitted pages if necessary. If a decommitted
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3280 * page is encountered, commit all needed adjacent decommitted
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3281 * pages in one operation, in order to reduce system call
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3282 * overhead.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3283 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3284 if (chunk->map[run_ind + i].bits & CHUNK_MAP_DECOMMITTED) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3285 size_t j;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3286
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3287 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3288 * Advance i+j to just past the index of the last page
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3289 * to commit. Clear CHUNK_MAP_DECOMMITTED along the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3290 * way.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3291 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3292 for (j = 0; i + j < need_pages && (chunk->map[run_ind +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3293 i + j].bits & CHUNK_MAP_DECOMMITTED); j++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3294 chunk->map[run_ind + i + j].bits ^=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3295 CHUNK_MAP_DECOMMITTED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3296 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3297
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3298 pages_commit((void *)((uintptr_t)chunk + ((run_ind + i)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3299 << pagesize_2pow)), (j << pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3300 # ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3301 arena->stats.ncommit++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3302 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3303 } else /* No need to zero since commit zeros. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3304 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3305
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3306 /* Zero if necessary. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3307 if (zero) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3308 if ((chunk->map[run_ind + i].bits & CHUNK_MAP_ZEROED)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3309 == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3310 VALGRIND_MALLOCLIKE_BLOCK((void *)((uintptr_t)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3311 chunk + ((run_ind + i) << pagesize_2pow)),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3312 pagesize, 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3313 memset((void *)((uintptr_t)chunk + ((run_ind
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3314 + i) << pagesize_2pow)), 0, pagesize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3315 VALGRIND_FREELIKE_BLOCK((void *)((uintptr_t)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3316 chunk + ((run_ind + i) << pagesize_2pow)),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3317 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3318 /* CHUNK_MAP_ZEROED is cleared below. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3319 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3320 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3321
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3322 /* Update dirty page accounting. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3323 if (chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3324 chunk->ndirty--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3325 arena->ndirty--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3326 /* CHUNK_MAP_DIRTY is cleared below. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3327 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3328
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3329 /* Initialize the chunk map. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3330 if (large) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3331 chunk->map[run_ind + i].bits = CHUNK_MAP_LARGE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3332 | CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3333 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3334 chunk->map[run_ind + i].bits = (size_t)run
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3335 | CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3336 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3337 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3338
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3339 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3340 * Set the run size only in the first element for large runs. This is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3341 * primarily a debugging aid, since the lack of size info for trailing
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3342 * pages only matters if the application tries to operate on an
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3343 * interior pointer.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3344 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3345 if (large)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3346 chunk->map[run_ind].bits |= size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3347
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3348 if (chunk->ndirty == 0 && old_ndirty > 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3349 arena_chunk_tree_dirty_remove(&arena->chunks_dirty, chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3350 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3351
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3352 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3353 arena_chunk_init(arena_t *arena, arena_chunk_t *chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3354 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3355 arena_run_t *run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3356 size_t i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3357
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3358 VALGRIND_MALLOCLIKE_BLOCK(chunk, (arena_chunk_header_npages <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3359 pagesize_2pow), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3360 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3361 arena->stats.mapped += chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3362 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3363
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3364 chunk->arena = arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3365
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3366 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3367 * Claim that no pages are in use, since the header is merely overhead.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3368 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3369 chunk->ndirty = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3370
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3371 /* Initialize the map to contain one maximal free untouched run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3372 run = (arena_run_t *)((uintptr_t)chunk + (arena_chunk_header_npages <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3373 pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3374 for (i = 0; i < arena_chunk_header_npages; i++)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3375 chunk->map[i].bits = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3376 chunk->map[i].bits = arena_maxclass
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3377 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3378 | CHUNK_MAP_DECOMMITTED
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3379 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3380 | CHUNK_MAP_ZEROED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3381 for (i++; i < chunk_npages-1; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3382 chunk->map[i].bits =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3383 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3384 CHUNK_MAP_DECOMMITTED |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3385 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3386 CHUNK_MAP_ZEROED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3387 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3388 chunk->map[chunk_npages-1].bits = arena_maxclass
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3389 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3390 | CHUNK_MAP_DECOMMITTED
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3391 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3392 | CHUNK_MAP_ZEROED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3393
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3394 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3395 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3396 * Start out decommitted, in order to force a closer correspondence
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3397 * between dirty pages and committed untouched pages.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3398 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3399 pages_decommit(run, arena_maxclass);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3400 # ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3401 arena->stats.ndecommit++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3402 arena->stats.decommitted += (chunk_npages - arena_chunk_header_npages);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3403 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3404 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3405
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3406 /* Insert the run into the runs_avail tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3407 arena_avail_tree_insert(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3408 &chunk->map[arena_chunk_header_npages]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3409 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3410
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3411 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3412 arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3413 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3414
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3415 if (arena->spare != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3416 if (arena->spare->ndirty > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3417 arena_chunk_tree_dirty_remove(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3418 &chunk->arena->chunks_dirty, arena->spare);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3419 arena->ndirty -= arena->spare->ndirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3420 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3421 VALGRIND_FREELIKE_BLOCK(arena->spare, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3422 chunk_dealloc((void *)arena->spare, chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3423 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3424 arena->stats.mapped -= chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3425 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3426 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3427
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3428 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3429 * Remove run from runs_avail, regardless of whether this chunk
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3430 * will be cached, so that the arena does not use it. Dirty page
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3431 * flushing only uses the chunks_dirty tree, so leaving this chunk in
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3432 * the chunks_* trees is sufficient for that purpose.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3433 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3434 arena_avail_tree_remove(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3435 &chunk->map[arena_chunk_header_npages]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3436
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3437 arena->spare = chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3438 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3439
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3440 static arena_run_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3441 arena_run_alloc(arena_t *arena, arena_bin_t *bin, size_t size, bool large,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3442 bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3443 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3444 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3445 arena_run_t *run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3446 arena_chunk_map_t *mapelm, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3447
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3448 assert(size <= arena_maxclass);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3449 assert((size & pagesize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3450
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3451 chunk = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3452 while (true) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3453 /* Search the arena's chunks for the lowest best fit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3454 key.bits = size | CHUNK_MAP_KEY;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3455 mapelm = arena_avail_tree_nsearch(&arena->runs_avail, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3456 if (mapelm != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3457 arena_chunk_t *run_chunk = (arena_chunk_t*)CHUNK_ADDR2BASE(mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3458 size_t pageind = ((uintptr_t)mapelm -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3459 (uintptr_t)run_chunk->map) /
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3460 sizeof(arena_chunk_map_t);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3461
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3462 if (chunk != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3463 chunk_dealloc(chunk, chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3464 run = (arena_run_t *)((uintptr_t)run_chunk + (pageind
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3465 << pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3466 arena_run_split(arena, run, size, large, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3467 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3468 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3469
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3470 if (arena->spare != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3471 /* Use the spare. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3472 chunk = arena->spare;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3473 arena->spare = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3474 run = (arena_run_t *)((uintptr_t)chunk +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3475 (arena_chunk_header_npages << pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3476 /* Insert the run into the runs_avail tree. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3477 arena_avail_tree_insert(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3478 &chunk->map[arena_chunk_header_npages]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3479 arena_run_split(arena, run, size, large, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3480 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3481 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3482
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3483 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3484 * No usable runs. Create a new chunk from which to allocate
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3485 * the run.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3486 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3487 if (chunk == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3488 uint64_t chunk_seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3489
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3490 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3491 * Record the chunk allocation sequence number in order
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3492 * to detect races.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3493 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3494 arena->chunk_seq++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3495 chunk_seq = arena->chunk_seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3496
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3497 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3498 * Drop the arena lock while allocating a chunk, since
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3499 * reserve notifications may cause recursive
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3500 * allocation. Dropping the lock here opens an
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3501 * allocataion race, but we recover.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3502 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3503 malloc_mutex_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3504 chunk = (arena_chunk_t *)chunk_alloc(chunksize, true,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3505 true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3506 malloc_mutex_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3507
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3508 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3509 * Check whether a race allowed a usable run to appear.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3510 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3511 if (bin != NULL && (run = bin->runcur) != NULL &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3512 run->nfree > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3513 if (chunk != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3514 chunk_dealloc(chunk, chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3515 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3516 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3517
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3518 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3519 * If this thread raced with another such that multiple
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3520 * chunks were allocated, make sure that there is still
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3521 * inadequate space before using this chunk.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3522 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3523 if (chunk_seq != arena->chunk_seq)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3524 continue;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3525
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3526 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3527 * Check for an error *after* checking for a race,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3528 * since a race could also cause a transient OOM
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3529 * condition.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3530 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3531 if (chunk == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3532 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3533 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3534
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3535 arena_chunk_init(arena, chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3536 run = (arena_run_t *)((uintptr_t)chunk +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3537 (arena_chunk_header_npages << pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3538 /* Update page map. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3539 arena_run_split(arena, run, size, large, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3540 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3541 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3542 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3543
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3544 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3545 arena_purge(arena_t *arena)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3546 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3547 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3548 size_t i, npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3549 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3550 size_t ndirty = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3551 rb_foreach_begin(arena_chunk_t, link_dirty, &arena->chunks_dirty,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3552 chunk) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3553 ndirty += chunk->ndirty;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3554 } rb_foreach_end(arena_chunk_t, link_dirty, &arena->chunks_dirty, chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3555 assert(ndirty == arena->ndirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3556 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3557 assert(arena->ndirty > opt_dirty_max);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3558
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3559 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3560 arena->stats.npurge++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3561 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3562
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3563 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3564 * Iterate downward through chunks until enough dirty memory has been
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3565 * purged. Terminate as soon as possible in order to minimize the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3566 * number of system calls, even if a chunk has only been partially
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3567 * purged.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3568 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3569 while (arena->ndirty > (opt_dirty_max >> 1)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3570 chunk = arena_chunk_tree_dirty_last(&arena->chunks_dirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3571 assert(chunk != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3572
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3573 for (i = chunk_npages - 1; chunk->ndirty > 0; i--) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3574 assert(i >= arena_chunk_header_npages);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3575
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3576 if (chunk->map[i].bits & CHUNK_MAP_DIRTY) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3577 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3578 assert((chunk->map[i].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3579 CHUNK_MAP_DECOMMITTED) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3580 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3581 chunk->map[i].bits ^=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3582 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3583 CHUNK_MAP_DECOMMITTED |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3584 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3585 CHUNK_MAP_DIRTY;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3586 /* Find adjacent dirty run(s). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3587 for (npages = 1; i > arena_chunk_header_npages
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3588 && (chunk->map[i - 1].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3589 CHUNK_MAP_DIRTY); npages++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3590 i--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3591 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3592 assert((chunk->map[i].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3593 CHUNK_MAP_DECOMMITTED) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3594 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3595 chunk->map[i].bits ^=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3596 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3597 CHUNK_MAP_DECOMMITTED |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3598 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3599 CHUNK_MAP_DIRTY;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3600 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3601 chunk->ndirty -= npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3602 arena->ndirty -= npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3603
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3604 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3605 pages_decommit((void *)((uintptr_t)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3606 chunk + (i << pagesize_2pow)),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3607 (npages << pagesize_2pow));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3608 # ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3609 arena->stats.ndecommit++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3610 arena->stats.decommitted += npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3611 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3612 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3613 madvise((void *)((uintptr_t)chunk + (i <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3614 pagesize_2pow)), (npages << pagesize_2pow),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3615 MADV_FREE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3616 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3617 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3618 arena->stats.nmadvise++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3619 arena->stats.purged += npages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3620 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3621 if (arena->ndirty <= (opt_dirty_max >> 1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3622 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3623 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3624 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3625
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3626 if (chunk->ndirty == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3627 arena_chunk_tree_dirty_remove(&arena->chunks_dirty,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3628 chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3629 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3630 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3631 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3632
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3633 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3634 arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3635 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3636 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3637 size_t size, run_ind, run_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3638
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3639 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3640 run_ind = (size_t)(((uintptr_t)run - (uintptr_t)chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3641 >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3642 assert(run_ind >= arena_chunk_header_npages);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3643 assert(run_ind < chunk_npages);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3644 if ((chunk->map[run_ind].bits & CHUNK_MAP_LARGE) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3645 size = chunk->map[run_ind].bits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3646 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3647 size = run->bin->run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3648 run_pages = (size >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3649
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3650 /* Mark pages as unallocated in the chunk map. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3651 if (dirty) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3652 size_t i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3653
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3654 for (i = 0; i < run_pages; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3655 assert((chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3656 == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3657 chunk->map[run_ind + i].bits = CHUNK_MAP_DIRTY;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3658 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3659
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3660 if (chunk->ndirty == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3661 arena_chunk_tree_dirty_insert(&arena->chunks_dirty,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3662 chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3663 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3664 chunk->ndirty += run_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3665 arena->ndirty += run_pages;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3666 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3667 size_t i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3668
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3669 for (i = 0; i < run_pages; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3670 chunk->map[run_ind + i].bits &= ~(CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3671 CHUNK_MAP_ALLOCATED);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3672 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3673 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3674 chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3675 pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3676 chunk->map[run_ind+run_pages-1].bits = size |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3677 (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3678
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3679 /* Try to coalesce forward. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3680 if (run_ind + run_pages < chunk_npages &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3681 (chunk->map[run_ind+run_pages].bits & CHUNK_MAP_ALLOCATED) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3682 size_t nrun_size = chunk->map[run_ind+run_pages].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3683 ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3684
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3685 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3686 * Remove successor from runs_avail; the coalesced run is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3687 * inserted later.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3688 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3689 arena_avail_tree_remove(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3690 &chunk->map[run_ind+run_pages]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3691
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3692 size += nrun_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3693 run_pages = size >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3694
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3695 assert((chunk->map[run_ind+run_pages-1].bits & ~pagesize_mask)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3696 == nrun_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3697 chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3698 pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3699 chunk->map[run_ind+run_pages-1].bits = size |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3700 (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3701 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3702
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3703 /* Try to coalesce backward. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3704 if (run_ind > arena_chunk_header_npages && (chunk->map[run_ind-1].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3705 CHUNK_MAP_ALLOCATED) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3706 size_t prun_size = chunk->map[run_ind-1].bits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3707
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3708 run_ind -= prun_size >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3709
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3710 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3711 * Remove predecessor from runs_avail; the coalesced run is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3712 * inserted later.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3713 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3714 arena_avail_tree_remove(&arena->runs_avail,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3715 &chunk->map[run_ind]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3716
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3717 size += prun_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3718 run_pages = size >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3719
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3720 assert((chunk->map[run_ind].bits & ~pagesize_mask) ==
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3721 prun_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3722 chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3723 pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3724 chunk->map[run_ind+run_pages-1].bits = size |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3725 (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3726 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3727
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3728 /* Insert into runs_avail, now that coalescing is complete. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3729 arena_avail_tree_insert(&arena->runs_avail, &chunk->map[run_ind]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3730
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3731 /* Deallocate chunk if it is now completely unused. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3732 if ((chunk->map[arena_chunk_header_npages].bits & (~pagesize_mask |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3733 CHUNK_MAP_ALLOCATED)) == arena_maxclass)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3734 arena_chunk_dealloc(arena, chunk);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3735
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3736 /* Enforce opt_dirty_max. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3737 if (arena->ndirty > opt_dirty_max)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3738 arena_purge(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3739 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3740
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3741 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3742 arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3743 size_t oldsize, size_t newsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3744 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3745 size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3746 size_t head_npages = (oldsize - newsize) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3747
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3748 assert(oldsize > newsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3749
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3750 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3751 * Update the chunk map so that arena_run_dalloc() can treat the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3752 * leading run as separately allocated.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3753 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3754 chunk->map[pageind].bits = (oldsize - newsize) | CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3755 CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3756 chunk->map[pageind+head_npages].bits = newsize | CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3757 CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3758
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3759 arena_run_dalloc(arena, run, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3760 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3761
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3762 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3763 arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3764 size_t oldsize, size_t newsize, bool dirty)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3765 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3766 size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3767 size_t npages = newsize >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3768
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3769 assert(oldsize > newsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3770
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3771 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3772 * Update the chunk map so that arena_run_dalloc() can treat the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3773 * trailing run as separately allocated.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3774 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3775 chunk->map[pageind].bits = newsize | CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3776 CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3777 chunk->map[pageind+npages].bits = (oldsize - newsize) | CHUNK_MAP_LARGE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3778 | CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3779
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3780 arena_run_dalloc(arena, (arena_run_t *)((uintptr_t)run + newsize),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3781 dirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3782 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3783
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3784 static arena_run_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3785 arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3786 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3787 arena_chunk_map_t *mapelm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3788 arena_run_t *run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3789 unsigned i, remainder;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3790
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3791 /* Look for a usable run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3792 mapelm = arena_run_tree_first(&bin->runs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3793 if (mapelm != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3794 /* run is guaranteed to have available space. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3795 arena_run_tree_remove(&bin->runs, mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3796 run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3797 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3798 bin->stats.reruns++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3799 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3800 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3801 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3802 /* No existing runs have any space available. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3803
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3804 /* Allocate a new run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3805 run = arena_run_alloc(arena, bin, bin->run_size, false, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3806 if (run == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3807 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3808 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3809 * Don't initialize if a race in arena_run_alloc() allowed an existing
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3810 * run to become usable.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3811 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3812 if (run == bin->runcur)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3813 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3814
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3815 VALGRIND_MALLOCLIKE_BLOCK(run, sizeof(arena_run_t) + (sizeof(unsigned) *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3816 (bin->regs_mask_nelms - 1)), 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3817
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3818 /* Initialize run internals. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3819 run->bin = bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3820
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3821 for (i = 0; i < bin->regs_mask_nelms - 1; i++)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3822 run->regs_mask[i] = UINT_MAX;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3823 remainder = bin->nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3824 if (remainder == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3825 run->regs_mask[i] = UINT_MAX;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3826 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3827 /* The last element has spare bits that need to be unset. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3828 run->regs_mask[i] = (UINT_MAX >> ((1U << (SIZEOF_INT_2POW + 3))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3829 - remainder));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3830 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3831
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3832 run->regs_minelm = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3833
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3834 run->nfree = bin->nregs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3835 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3836 run->magic = ARENA_RUN_MAGIC;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3837 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3838
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3839 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3840 bin->stats.nruns++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3841 bin->stats.curruns++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3842 if (bin->stats.curruns > bin->stats.highruns)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3843 bin->stats.highruns = bin->stats.curruns;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3844 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3845 return (run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3846 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3847
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3848 /* bin->runcur must have space available before this function is called. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3849 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3850 arena_bin_malloc_easy(arena_t *arena, arena_bin_t *bin, arena_run_t *run)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3851 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3852 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3853
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3854 assert(run->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3855 assert(run->nfree > 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3856
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3857 ret = arena_run_reg_alloc(run, bin);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3858 assert(ret != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3859 run->nfree--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3860
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3861 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3862 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3863
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3864 /* Re-fill bin->runcur, then call arena_bin_malloc_easy(). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3865 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3866 arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3867 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3868
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3869 bin->runcur = arena_bin_nonfull_run_get(arena, bin);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3870 if (bin->runcur == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3871 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3872 assert(bin->runcur->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3873 assert(bin->runcur->nfree > 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3874
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3875 return (arena_bin_malloc_easy(arena, bin, bin->runcur));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3876 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3877
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3878 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3879 * Calculate bin->run_size such that it meets the following constraints:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3880 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3881 * *) bin->run_size >= min_run_size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3882 * *) bin->run_size <= arena_maxclass
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3883 * *) bin->run_size <= RUN_MAX_SMALL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3884 * *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3885 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3886 * bin->nregs, bin->regs_mask_nelms, and bin->reg0_offset are
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3887 * also calculated here, since these settings are all interdependent.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3888 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3889 static size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3890 arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3891 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3892 size_t try_run_size, good_run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3893 unsigned good_nregs, good_mask_nelms, good_reg0_offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3894 unsigned try_nregs, try_mask_nelms, try_reg0_offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3895
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3896 assert(min_run_size >= pagesize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3897 assert(min_run_size <= arena_maxclass);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3898 assert(min_run_size <= RUN_MAX_SMALL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3899
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3900 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3901 * Calculate known-valid settings before entering the run_size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3902 * expansion loop, so that the first part of the loop always copies
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3903 * valid settings.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3904 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3905 * The do..while loop iteratively reduces the number of regions until
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3906 * the run header and the regions no longer overlap. A closed formula
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3907 * would be quite messy, since there is an interdependency between the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3908 * header's mask length and the number of regions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3909 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3910 try_run_size = min_run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3911 try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin->reg_size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3912 + 1; /* Counter-act try_nregs-- in loop. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3913 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3914 try_nregs--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3915 try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3916 ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ? 1 : 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3917 try_reg0_offset = try_run_size - (try_nregs * bin->reg_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3918 } while (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3919 > try_reg0_offset);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3920
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3921 /* run_size expansion loop. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3922 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3923 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3924 * Copy valid settings before trying more aggressive settings.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3925 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3926 good_run_size = try_run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3927 good_nregs = try_nregs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3928 good_mask_nelms = try_mask_nelms;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3929 good_reg0_offset = try_reg0_offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3930
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3931 /* Try more aggressive settings. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3932 try_run_size += pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3933 try_nregs = ((try_run_size - sizeof(arena_run_t)) /
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3934 bin->reg_size) + 1; /* Counter-act try_nregs-- in loop. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3935 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3936 try_nregs--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3937 try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3938 ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3939 1 : 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3940 try_reg0_offset = try_run_size - (try_nregs *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3941 bin->reg_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3942 } while (sizeof(arena_run_t) + (sizeof(unsigned) *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3943 (try_mask_nelms - 1)) > try_reg0_offset);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3944 } while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3945 && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3946 && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3947
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3948 assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3949 <= good_reg0_offset);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3950 assert((good_mask_nelms << (SIZEOF_INT_2POW + 3)) >= good_nregs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3951
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3952 /* Copy final settings. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3953 bin->run_size = good_run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3954 bin->nregs = good_nregs;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3955 bin->regs_mask_nelms = good_mask_nelms;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3956 bin->reg0_offset = good_reg0_offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3957
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3958 return (good_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3959 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3960
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3961 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3962 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3963 arena_lock_balance(arena_t *arena)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3964 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3965 unsigned contention;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3966
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3967 contention = malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3968 if (narenas > 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3969 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3970 * Calculate the exponentially averaged contention for this
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3971 * arena. Due to integer math always rounding down, this value
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3972 * decays somewhat faster then normal.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3973 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3974 arena->contention = (((uint64_t)arena->contention
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3975 * (uint64_t)((1U << BALANCE_ALPHA_INV_2POW)-1))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3976 + (uint64_t)contention) >> BALANCE_ALPHA_INV_2POW;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3977 if (arena->contention >= opt_balance_threshold)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3978 arena_lock_balance_hard(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3979 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3980 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3981
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3982 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3983 arena_lock_balance_hard(arena_t *arena)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3984 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3985 uint32_t ind;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3986
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3987 arena->contention = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3988 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3989 arena->stats.nbalance++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3990 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3991 ind = PRN(balance, narenas_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3992 if (arenas[ind] != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3993 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3994 TlsSetValue(tlsIndex, arenas[ind]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3995 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3996 arenas_map = arenas[ind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3997 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3998 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
3999 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4000 if (arenas[ind] != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4001 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4002 TlsSetValue(tlsIndex, arenas[ind]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4003 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4004 arenas_map = arenas[ind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4005 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4006 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4007 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4008 TlsSetValue(tlsIndex, arenas_extend(ind));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4009 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4010 arenas_map = arenas_extend(ind);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4011 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4012 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4013 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4014 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4015 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4016 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4017
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4018 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4019 arena_malloc_small(arena_t *arena, size_t size, bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4020 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4021 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4022 arena_bin_t *bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4023 arena_run_t *run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4024
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4025 if (size < small_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4026 /* Tiny. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4027 size = pow2_ceil(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4028 bin = &arena->bins[ffs((int)(size >> (TINY_MIN_2POW +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4029 1)))];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4030 #if (!defined(NDEBUG) || defined(MALLOC_STATS))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4031 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4032 * Bin calculation is always correct, but we may need
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4033 * to fix size for the purposes of assertions and/or
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4034 * stats accuracy.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4035 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4036 if (size < (1U << TINY_MIN_2POW))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4037 size = (1U << TINY_MIN_2POW);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4038 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4039 } else if (size <= small_max) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4040 /* Quantum-spaced. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4041 size = QUANTUM_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4042 bin = &arena->bins[ntbins + (size >> opt_quantum_2pow)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4043 - 1];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4044 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4045 /* Sub-page. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4046 size = pow2_ceil(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4047 bin = &arena->bins[ntbins + nqbins
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4048 + (ffs((int)(size >> opt_small_max_2pow)) - 2)];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4049 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4050 assert(size == bin->reg_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4051
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4052 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4053 arena_lock_balance(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4054 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4055 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4056 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4057 if ((run = bin->runcur) != NULL && run->nfree > 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4058 ret = arena_bin_malloc_easy(arena, bin, run);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4059 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4060 ret = arena_bin_malloc_hard(arena, bin);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4061
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4062 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4063 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4064 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4065 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4066
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4067 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4068 bin->stats.nrequests++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4069 arena->stats.nmalloc_small++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4070 arena->stats.allocated_small += size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4071 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4072 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4073
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4074 VALGRIND_MALLOCLIKE_BLOCK(ret, size, 0, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4075 if (zero == false) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4076 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4077 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4078 memset(ret, 0xa5, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4079 else if (opt_zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4080 memset(ret, 0, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4081 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4082 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4083 memset(ret, 0, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4084
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4085 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4086 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4087
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4088 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4089 arena_malloc_large(arena_t *arena, size_t size, bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4090 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4091 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4092
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4093 /* Large allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4094 size = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4095 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4096 arena_lock_balance(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4097 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4098 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4099 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4100 ret = (void *)arena_run_alloc(arena, NULL, size, true, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4101 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4102 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4103 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4104 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4105 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4106 arena->stats.nmalloc_large++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4107 arena->stats.allocated_large += size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4108 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4109 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4110
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4111 VALGRIND_MALLOCLIKE_BLOCK(ret, size, 0, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4112 if (zero == false) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4113 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4114 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4115 memset(ret, 0xa5, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4116 else if (opt_zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4117 memset(ret, 0, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4118 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4119 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4120
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4121 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4122 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4123
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4124 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4125 arena_malloc(arena_t *arena, size_t size, bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4126 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4127
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4128 assert(arena != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4129 assert(arena->magic == ARENA_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4130 assert(size != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4131 assert(QUANTUM_CEILING(size) <= arena_maxclass);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4132
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4133 if (size <= bin_maxclass) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4134 return (arena_malloc_small(arena, size, zero));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4135 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4136 return (arena_malloc_large(arena, size, zero));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4137 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4138
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4139 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4140 imalloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4141 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4142
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4143 assert(size != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4144
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4145 if (size <= arena_maxclass)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4146 return (arena_malloc(choose_arena(), size, false));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4147 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4148 return (huge_malloc(size, false));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4149 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4150
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4151 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4152 icalloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4153 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4154
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4155 if (size <= arena_maxclass)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4156 return (arena_malloc(choose_arena(), size, true));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4157 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4158 return (huge_malloc(size, true));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4159 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4160
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4161 /* Only handles large allocations that require more than page alignment. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4162 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4163 arena_palloc(arena_t *arena, size_t alignment, size_t size, size_t alloc_size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4164 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4165 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4166 size_t offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4167 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4168
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4169 assert((size & pagesize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4170 assert((alignment & pagesize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4171
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4172 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4173 arena_lock_balance(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4174 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4175 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4176 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4177 ret = (void *)arena_run_alloc(arena, NULL, alloc_size, true, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4178 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4179 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4180 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4181 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4182
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4183 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4184
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4185 offset = (uintptr_t)ret & (alignment - 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4186 assert((offset & pagesize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4187 assert(offset < alloc_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4188 if (offset == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4189 arena_run_trim_tail(arena, chunk, (arena_run_t*)ret, alloc_size, size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4190 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4191 size_t leadsize, trailsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4192
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4193 leadsize = alignment - offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4194 if (leadsize > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4195 arena_run_trim_head(arena, chunk, (arena_run_t*)ret, alloc_size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4196 alloc_size - leadsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4197 ret = (void *)((uintptr_t)ret + leadsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4198 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4199
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4200 trailsize = alloc_size - leadsize - size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4201 if (trailsize != 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4202 /* Trim trailing space. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4203 assert(trailsize < alloc_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4204 arena_run_trim_tail(arena, chunk, (arena_run_t*)ret, size + trailsize,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4205 size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4206 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4207 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4208
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4209 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4210 arena->stats.nmalloc_large++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4211 arena->stats.allocated_large += size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4212 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4213 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4214
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4215 VALGRIND_MALLOCLIKE_BLOCK(ret, size, 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4216 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4217 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4218 memset(ret, 0xa5, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4219 else if (opt_zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4220 memset(ret, 0, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4221 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4222 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4223 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4224
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4225 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4226 ipalloc(size_t alignment, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4227 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4228 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4229 size_t ceil_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4230
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4231 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4232 * Round size up to the nearest multiple of alignment.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4233 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4234 * This done, we can take advantage of the fact that for each small
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4235 * size class, every object is aligned at the smallest power of two
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4236 * that is non-zero in the base two representation of the size. For
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4237 * example:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4238 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4239 * Size | Base 2 | Minimum alignment
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4240 * -----+----------+------------------
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4241 * 96 | 1100000 | 32
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4242 * 144 | 10100000 | 32
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4243 * 192 | 11000000 | 64
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4244 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4245 * Depending on runtime settings, it is possible that arena_malloc()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4246 * will further round up to a power of two, but that never causes
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4247 * correctness issues.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4248 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4249 ceil_size = (size + (alignment - 1)) & (-alignment);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4250 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4251 * (ceil_size < size) protects against the combination of maximal
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4252 * alignment and size greater than maximal alignment.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4253 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4254 if (ceil_size < size) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4255 /* size_t overflow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4256 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4257 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4258
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4259 if (ceil_size <= pagesize || (alignment <= pagesize
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4260 && ceil_size <= arena_maxclass))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4261 ret = arena_malloc(choose_arena(), ceil_size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4262 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4263 size_t run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4264
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4265 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4266 * We can't achieve sub-page alignment, so round up alignment
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4267 * permanently; it makes later calculations simpler.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4268 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4269 alignment = PAGE_CEILING(alignment);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4270 ceil_size = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4271 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4272 * (ceil_size < size) protects against very large sizes within
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4273 * pagesize of SIZE_T_MAX.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4274 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4275 * (ceil_size + alignment < ceil_size) protects against the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4276 * combination of maximal alignment and ceil_size large enough
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4277 * to cause overflow. This is similar to the first overflow
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4278 * check above, but it needs to be repeated due to the new
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4279 * ceil_size value, which may now be *equal* to maximal
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4280 * alignment, whereas before we only detected overflow if the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4281 * original size was *greater* than maximal alignment.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4282 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4283 if (ceil_size < size || ceil_size + alignment < ceil_size) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4284 /* size_t overflow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4285 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4286 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4287
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4288 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4289 * Calculate the size of the over-size run that arena_palloc()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4290 * would need to allocate in order to guarantee the alignment.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4291 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4292 if (ceil_size >= alignment)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4293 run_size = ceil_size + alignment - pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4294 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4295 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4296 * It is possible that (alignment << 1) will cause
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4297 * overflow, but it doesn't matter because we also
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4298 * subtract pagesize, which in the case of overflow
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4299 * leaves us with a very large run_size. That causes
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4300 * the first conditional below to fail, which means
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4301 * that the bogus run_size value never gets used for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4302 * anything important.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4303 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4304 run_size = (alignment << 1) - pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4305 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4306
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4307 if (run_size <= arena_maxclass) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4308 ret = arena_palloc(choose_arena(), alignment, ceil_size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4309 run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4310 } else if (alignment <= chunksize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4311 ret = huge_malloc(ceil_size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4312 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4313 ret = huge_palloc(alignment, ceil_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4314 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4315
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4316 assert(((uintptr_t)ret & (alignment - 1)) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4317 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4318 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4319
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4320 /* Return the size of the allocation pointed to by ptr. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4321 static size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4322 arena_salloc(const void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4323 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4324 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4325 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4326 size_t pageind, mapbits;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4327
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4328 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4329 assert(CHUNK_ADDR2BASE(ptr) != ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4330
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4331 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4332 pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4333 mapbits = chunk->map[pageind].bits;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4334 assert((mapbits & CHUNK_MAP_ALLOCATED) != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4335 if ((mapbits & CHUNK_MAP_LARGE) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4336 arena_run_t *run = (arena_run_t *)(mapbits & ~pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4337 assert(run->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4338 ret = run->bin->reg_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4339 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4340 ret = mapbits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4341 assert(ret != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4342 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4343
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4344 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4345 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4346
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4347 #if (defined(MALLOC_VALIDATE) || defined(MOZ_MEMORY_DARWIN))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4348 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4349 * Validate ptr before assuming that it points to an allocation. Currently,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4350 * the following validation is performed:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4351 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4352 * + Check that ptr is not NULL.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4353 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4354 * + Check that ptr lies within a mapped chunk.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4355 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4356 static inline size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4357 isalloc_validate(const void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4358 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4359 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4360
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4361 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4362 if (chunk == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4363 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4364
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4365 if (malloc_rtree_get(chunk_rtree, (uintptr_t)chunk) == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4366 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4367
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4368 if (chunk != ptr) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4369 assert(chunk->arena->magic == ARENA_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4370 return (arena_salloc(ptr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4371 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4372 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4373 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4374 extent_node_t key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4375
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4376 /* Chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4377 key.addr = (void *)chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4378 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4379 node = extent_tree_ad_search(&huge, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4380 if (node != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4381 ret = node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4382 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4383 ret = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4384 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4385 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4386 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4387 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4388 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4389
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4390 static inline size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4391 isalloc(const void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4392 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4393 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4394 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4395
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4396 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4397
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4398 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4399 if (chunk != ptr) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4400 /* Region. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4401 assert(chunk->arena->magic == ARENA_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4402
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4403 ret = arena_salloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4404 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4405 extent_node_t *node, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4406
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4407 /* Chunk (huge allocation). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4408
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4409 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4410
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4411 /* Extract from tree of huge allocations. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4412 key.addr = __DECONST(void *, ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4413 node = extent_tree_ad_search(&huge, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4414 assert(node != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4415
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4416 ret = node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4417
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4418 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4419 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4420
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4421 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4422 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4423
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4424 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4425 arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4426 arena_chunk_map_t *mapelm)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4427 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4428 arena_run_t *run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4429 arena_bin_t *bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4430 size_t size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4431
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4432 run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4433 assert(run->magic == ARENA_RUN_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4434 bin = run->bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4435 size = bin->reg_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4436
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4437 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4438 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4439 memset(ptr, 0x5a, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4440 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4441
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4442 arena_run_reg_dalloc(run, bin, ptr, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4443 run->nfree++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4444
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4445 if (run->nfree == bin->nregs) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4446 /* Deallocate run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4447 if (run == bin->runcur)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4448 bin->runcur = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4449 else if (bin->nregs != 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4450 size_t run_pageind = (((uintptr_t)run -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4451 (uintptr_t)chunk)) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4452 arena_chunk_map_t *run_mapelm =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4453 &chunk->map[run_pageind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4454 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4455 * This block's conditional is necessary because if the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4456 * run only contains one region, then it never gets
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4457 * inserted into the non-full runs tree.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4458 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4459 assert(arena_run_tree_search(&bin->runs, run_mapelm) ==
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4460 run_mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4461 arena_run_tree_remove(&bin->runs, run_mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4462 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4463 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4464 run->magic = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4465 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4466 VALGRIND_FREELIKE_BLOCK(run, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4467 arena_run_dalloc(arena, run, true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4468 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4469 bin->stats.curruns--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4470 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4471 } else if (run->nfree == 1 && run != bin->runcur) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4472 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4473 * Make sure that bin->runcur always refers to the lowest
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4474 * non-full run, if one exists.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4475 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4476 if (bin->runcur == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4477 bin->runcur = run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4478 else if ((uintptr_t)run < (uintptr_t)bin->runcur) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4479 /* Switch runcur. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4480 if (bin->runcur->nfree > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4481 arena_chunk_t *runcur_chunk =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4482 (arena_chunk_t*)CHUNK_ADDR2BASE(bin->runcur);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4483 size_t runcur_pageind =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4484 (((uintptr_t)bin->runcur -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4485 (uintptr_t)runcur_chunk)) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4486 arena_chunk_map_t *runcur_mapelm =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4487 &runcur_chunk->map[runcur_pageind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4488
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4489 /* Insert runcur. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4490 assert(arena_run_tree_search(&bin->runs,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4491 runcur_mapelm) == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4492 arena_run_tree_insert(&bin->runs,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4493 runcur_mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4494 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4495 bin->runcur = run;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4496 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4497 size_t run_pageind = (((uintptr_t)run -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4498 (uintptr_t)chunk)) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4499 arena_chunk_map_t *run_mapelm =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4500 &chunk->map[run_pageind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4501
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4502 assert(arena_run_tree_search(&bin->runs, run_mapelm) ==
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4503 NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4504 arena_run_tree_insert(&bin->runs, run_mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4505 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4506 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4507 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4508 arena->stats.allocated_small -= size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4509 arena->stats.ndalloc_small++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4510 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4511 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4512
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4513 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4514 arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4515 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4516 /* Large allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4517 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4518
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4519 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4520 #ifndef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4521 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4522 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4523 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4524 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4525 size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4526 pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4527 size_t size = chunk->map[pageind].bits & ~pagesize_mask;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4528
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4529 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4530 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4531 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4532 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4533 memset(ptr, 0x5a, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4534 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4535 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4536 arena->stats.allocated_large -= size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4537 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4538 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4539 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4540 arena->stats.ndalloc_large++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4541 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4542
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4543 arena_run_dalloc(arena, (arena_run_t *)ptr, true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4544 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4545 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4546
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4547 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4548 arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4549 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4550 size_t pageind;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4551 arena_chunk_map_t *mapelm;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4552
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4553 assert(arena != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4554 assert(arena->magic == ARENA_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4555 assert(chunk->arena == arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4556 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4557 assert(CHUNK_ADDR2BASE(ptr) != ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4558
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4559 pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4560 mapelm = &chunk->map[pageind];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4561 assert((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4562 if ((mapelm->bits & CHUNK_MAP_LARGE) == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4563 /* Small allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4564 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4565 arena_dalloc_small(arena, chunk, ptr, mapelm);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4566 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4567 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4568 arena_dalloc_large(arena, chunk, ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4569 VALGRIND_FREELIKE_BLOCK(ptr, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4570 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4571
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4572 static inline void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4573 idalloc(void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4574 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4575 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4576
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4577 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4578
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4579 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4580 if (chunk != ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4581 arena_dalloc(chunk->arena, chunk, ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4582 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4583 huge_dalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4584 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4585
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4586 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4587 arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4588 size_t size, size_t oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4589 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4590
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4591 assert(size < oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4592
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4593 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4594 * Shrink the run, and make trailing pages available for other
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4595 * allocations.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4596 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4597 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4598 arena_lock_balance(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4599 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4600 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4601 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4602 arena_run_trim_tail(arena, chunk, (arena_run_t *)ptr, oldsize, size,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4603 true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4604 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4605 arena->stats.allocated_large -= oldsize - size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4606 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4607 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4608 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4609
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4610 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4611 arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4612 size_t size, size_t oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4613 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4614 size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4615 size_t npages = oldsize >> pagesize_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4616
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4617 assert(oldsize == (chunk->map[pageind].bits & ~pagesize_mask));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4618
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4619 /* Try to extend the run. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4620 assert(size > oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4621 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4622 arena_lock_balance(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4623 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4624 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4625 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4626 if (pageind + npages < chunk_npages && (chunk->map[pageind+npages].bits
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4627 & CHUNK_MAP_ALLOCATED) == 0 && (chunk->map[pageind+npages].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4628 ~pagesize_mask) >= size - oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4629 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4630 * The next run is available and sufficiently large. Split the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4631 * following run, then merge the first part with the existing
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4632 * allocation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4633 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4634 arena_run_split(arena, (arena_run_t *)((uintptr_t)chunk +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4635 ((pageind+npages) << pagesize_2pow)), size - oldsize, true,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4636 false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4637
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4638 chunk->map[pageind].bits = size | CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4639 CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4640 chunk->map[pageind+npages].bits = CHUNK_MAP_LARGE |
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4641 CHUNK_MAP_ALLOCATED;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4642
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4643 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4644 arena->stats.allocated_large += size - oldsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4645 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4646 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4647 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4648 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4649 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4650
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4651 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4652 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4653
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4654 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4655 * Try to resize a large allocation, in order to avoid copying. This will
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4656 * always fail if growing an object, and the following run is already in use.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4657 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4658 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4659 arena_ralloc_large(void *ptr, size_t size, size_t oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4660 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4661 size_t psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4662
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4663 psize = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4664 if (psize == oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4665 /* Same size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4666 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4667 if (opt_junk && size < oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4668 memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4669 size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4670 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4671 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4672 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4673 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4674 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4675 arena_t *arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4676
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4677 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4678 arena = chunk->arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4679 assert(arena->magic == ARENA_MAGIC);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4680
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4681 if (psize < oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4682 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4683 /* Fill before shrinking in order avoid a race. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4684 if (opt_junk) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4685 memset((void *)((uintptr_t)ptr + size), 0x5a,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4686 oldsize - size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4687 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4688 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4689 arena_ralloc_large_shrink(arena, chunk, ptr, psize,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4690 oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4691 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4692 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4693 bool ret = arena_ralloc_large_grow(arena, chunk, ptr,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4694 psize, oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4695 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4696 if (ret == false && opt_zero) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4697 memset((void *)((uintptr_t)ptr + oldsize), 0,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4698 size - oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4699 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4700 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4701 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4702 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4703 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4704 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4705
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4706 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4707 arena_ralloc(void *ptr, size_t size, size_t oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4708 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4709 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4710 size_t copysize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4711
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4712 /* Try to avoid moving the allocation. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4713 if (size < small_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4714 if (oldsize < small_min &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4715 ffs((int)(pow2_ceil(size) >> (TINY_MIN_2POW + 1)))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4716 == ffs((int)(pow2_ceil(oldsize) >> (TINY_MIN_2POW + 1))))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4717 goto IN_PLACE; /* Same size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4718 } else if (size <= small_max) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4719 if (oldsize >= small_min && oldsize <= small_max &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4720 (QUANTUM_CEILING(size) >> opt_quantum_2pow)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4721 == (QUANTUM_CEILING(oldsize) >> opt_quantum_2pow))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4722 goto IN_PLACE; /* Same size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4723 } else if (size <= bin_maxclass) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4724 if (oldsize > small_max && oldsize <= bin_maxclass &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4725 pow2_ceil(size) == pow2_ceil(oldsize))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4726 goto IN_PLACE; /* Same size class. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4727 } else if (oldsize > bin_maxclass && oldsize <= arena_maxclass) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4728 assert(size > bin_maxclass);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4729 if (arena_ralloc_large(ptr, size, oldsize) == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4730 return (ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4731 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4732
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4733 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4734 * If we get here, then size and oldsize are different enough that we
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4735 * need to move the object. In that case, fall back to allocating new
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4736 * space and copying.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4737 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4738 ret = arena_malloc(choose_arena(), size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4739 if (ret == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4740 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4741
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4742 /* Junk/zero-filling were already done by arena_malloc(). */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4743 copysize = (size < oldsize) ? size : oldsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4744 #ifdef VM_COPY_MIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4745 if (copysize >= VM_COPY_MIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4746 pages_copy(ret, ptr, copysize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4747 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4748 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4749 memcpy(ret, ptr, copysize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4750 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4751 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4752 IN_PLACE:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4753 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4754 if (opt_junk && size < oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4755 memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize - size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4756 else if (opt_zero && size > oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4757 memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4758 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4759 return (ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4760 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4761
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4762 static inline void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4763 iralloc(void *ptr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4764 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4765 size_t oldsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4766
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4767 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4768 assert(size != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4769
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4770 oldsize = isalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4771
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4772 #ifndef MALLOC_VALGRIND
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4773 if (size <= arena_maxclass)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4774 return (arena_ralloc(ptr, size, oldsize));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4775 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4776 return (huge_ralloc(ptr, size, oldsize));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4777 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4778 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4779 * Valgrind does not provide a public interface for modifying an
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4780 * existing allocation, so use malloc/memcpy/free instead.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4781 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4782 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4783 void *ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4784 if (ret != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4785 if (oldsize < size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4786 memcpy(ret, ptr, oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4787 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4788 memcpy(ret, ptr, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4789 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4790 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4791 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4792 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4793 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4794 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4795
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4796 static bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4797 arena_new(arena_t *arena)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4798 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4799 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4800 arena_bin_t *bin;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4801 size_t pow2_size, prev_run_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4802
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4803 if (malloc_spin_init(&arena->lock))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4804 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4805
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4806 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4807 memset(&arena->stats, 0, sizeof(arena_stats_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4808 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4809
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4810 arena->chunk_seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4811
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4812 /* Initialize chunks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4813 arena_chunk_tree_dirty_new(&arena->chunks_dirty);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4814 arena->spare = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4815
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4816 arena->ndirty = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4817
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4818 arena_avail_tree_new(&arena->runs_avail);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4819
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4820 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4821 arena->contention = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4822 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4823
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4824 /* Initialize bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4825 prev_run_size = pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4826
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4827 /* (2^n)-spaced tiny bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4828 for (i = 0; i < ntbins; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4829 bin = &arena->bins[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4830 bin->runcur = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4831 arena_run_tree_new(&bin->runs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4832
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4833 bin->reg_size = (1U << (TINY_MIN_2POW + i));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4834
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4835 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4836
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4837 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4838 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4839 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4840 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4841
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4842 /* Quantum-spaced bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4843 for (; i < ntbins + nqbins; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4844 bin = &arena->bins[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4845 bin->runcur = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4846 arena_run_tree_new(&bin->runs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4847
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4848 bin->reg_size = quantum * (i - ntbins + 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4849
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4850 pow2_size = pow2_ceil(quantum * (i - ntbins + 1));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4851 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4852
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4853 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4854 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4855 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4856 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4857
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4858 /* (2^n)-spaced sub-page bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4859 for (; i < ntbins + nqbins + nsbins; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4860 bin = &arena->bins[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4861 bin->runcur = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4862 arena_run_tree_new(&bin->runs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4863
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4864 bin->reg_size = (small_max << (i - (ntbins + nqbins) + 1));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4865
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4866 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4867
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4868 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4869 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4870 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4871 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4872
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4873 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4874 arena->magic = ARENA_MAGIC;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4875 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4876
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4877 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4878 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4879
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4880 /* Create a new arena and insert it into the arenas array at index ind. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4881 static arena_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4882 arenas_extend(unsigned ind)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4883 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4884 arena_t *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4885
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4886 /* Allocate enough space for trailing bins. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4887 ret = (arena_t *)base_alloc(sizeof(arena_t)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4888 + (sizeof(arena_bin_t) * (ntbins + nqbins + nsbins - 1)));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4889 if (ret != NULL && arena_new(ret) == false) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4890 arenas[ind] = ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4891 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4892 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4893 /* Only reached if there is an OOM error. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4894
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4895 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4896 * OOM here is quite inconvenient to propagate, since dealing with it
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4897 * would require a check for failure in the fast path. Instead, punt
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4898 * by using arenas[0]. In practice, this is an extremely unlikely
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4899 * failure.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4900 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4901 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4902 ": (malloc) Error initializing arena\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4903 if (opt_abort)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4904 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4905
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4906 return (arenas[0]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4907 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4908
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4909 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4910 * End arena.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4911 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4912 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4913 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4914 * Begin general internal functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4915 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4916
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4917 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4918 huge_malloc(size_t size, bool zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4919 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4920 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4921 size_t csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4922 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4923 size_t psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4924 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4925 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4926
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4927 /* Allocate one or more contiguous chunks for this request. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4928
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4929 csize = CHUNK_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4930 if (csize == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4931 /* size is large enough to cause size_t wrap-around. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4932 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4933 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4934
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4935 /* Allocate an extent node with which to track the chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4936 node = base_node_alloc();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4937 if (node == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4938 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4939
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4940 ret = chunk_alloc(csize, zero, true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4941 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4942 base_node_dealloc(node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4943 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4944 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4945
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4946 /* Insert node into huge. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4947 node->addr = ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4948 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4949 psize = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4950 node->size = psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4951 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4952 node->size = csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4953 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4954
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4955 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4956 extent_tree_ad_insert(&huge, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4957 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4958 huge_nmalloc++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4959 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4960 huge_allocated += psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4961 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4962 huge_allocated += csize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4963 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4964 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4965 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4966
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4967 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4968 if (csize - psize > 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4969 pages_decommit((void *)((uintptr_t)ret + psize), csize - psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4970 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4971
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4972 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4973 VALGRIND_MALLOCLIKE_BLOCK(ret, psize, 0, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4974 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4975 VALGRIND_MALLOCLIKE_BLOCK(ret, csize, 0, zero);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4976 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4977
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4978 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4979 if (zero == false) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4980 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4981 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4982 memset(ret, 0xa5, psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4983 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4984 memset(ret, 0xa5, csize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4985 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4986 else if (opt_zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4987 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4988 memset(ret, 0, psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4989 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4990 memset(ret, 0, csize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4991 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4992 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4993 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4994
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4995 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4996 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4997
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4998 /* Only handles large allocations that require more than chunk alignment. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
4999 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5000 huge_palloc(size_t alignment, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5001 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5002 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5003 size_t alloc_size, chunk_size, offset;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5004 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5005 size_t psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5006 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5007 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5008 int pfd;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5009
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5010 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5011 * This allocation requires alignment that is even larger than chunk
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5012 * alignment. This means that huge_malloc() isn't good enough.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5013 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5014 * Allocate almost twice as many chunks as are demanded by the size or
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5015 * alignment, in order to assure the alignment can be achieved, then
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5016 * unmap leading and trailing chunks.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5017 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5018 assert(alignment >= chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5019
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5020 chunk_size = CHUNK_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5021
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5022 if (size >= alignment)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5023 alloc_size = chunk_size + alignment - chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5024 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5025 alloc_size = (alignment << 1) - chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5026
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5027 /* Allocate an extent node with which to track the chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5028 node = base_node_alloc();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5029 if (node == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5030 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5031
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5032 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5033 * Windows requires that there be a 1:1 mapping between VM
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5034 * allocation/deallocation operations. Therefore, take care here to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5035 * acquire the final result via one mapping operation.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5036 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5037 * The MALLOC_PAGEFILE code also benefits from this mapping algorithm,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5038 * since it reduces the number of page files.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5039 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5040 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5041 if (opt_pagefile) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5042 pfd = pagefile_init(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5043 if (pfd == -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5044 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5045 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5046 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5047 pfd = -1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5048 #ifdef JEMALLOC_USES_MAP_ALIGN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5049 ret = pages_map_align(chunk_size, pfd, alignment);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5050 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5051 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5052 void *over;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5053
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5054 over = chunk_alloc(alloc_size, false, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5055 if (over == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5056 base_node_dealloc(node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5057 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5058 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5059 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5060
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5061 offset = (uintptr_t)over & (alignment - 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5062 assert((offset & chunksize_mask) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5063 assert(offset < alloc_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5064 ret = (void *)((uintptr_t)over + offset);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5065 chunk_dealloc(over, alloc_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5066 ret = pages_map(ret, chunk_size, pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5067 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5068 * Failure here indicates a race with another thread, so try
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5069 * again.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5070 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5071 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5072 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5073 /* Insert node into huge. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5074 node->addr = ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5075 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5076 psize = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5077 node->size = psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5078 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5079 node->size = chunk_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5080 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5081
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5082 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5083 extent_tree_ad_insert(&huge, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5084 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5085 huge_nmalloc++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5086 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5087 huge_allocated += psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5088 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5089 huge_allocated += chunk_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5090 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5091 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5092 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5093
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5094 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5095 if (chunk_size - psize > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5096 pages_decommit((void *)((uintptr_t)ret + psize),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5097 chunk_size - psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5098 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5099 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5100
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5101 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5102 VALGRIND_MALLOCLIKE_BLOCK(ret, psize, 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5103 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5104 VALGRIND_MALLOCLIKE_BLOCK(ret, chunk_size, 0, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5105 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5106
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5107 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5108 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5109 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5110 memset(ret, 0xa5, psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5111 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5112 memset(ret, 0xa5, chunk_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5113 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5114 else if (opt_zero)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5115 # ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5116 memset(ret, 0, psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5117 # else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5118 memset(ret, 0, chunk_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5119 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5120 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5121
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5122 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5123 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5124 if (pfd != -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5125 pagefile_close(pfd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5126 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5127 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5128 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5129
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5130 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5131 huge_ralloc(void *ptr, size_t size, size_t oldsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5132 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5133 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5134 size_t copysize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5135
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5136 /* Avoid moving the allocation if the size class would not change. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5137
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5138 if (oldsize > arena_maxclass &&
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5139 CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5140 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5141 size_t psize = PAGE_CEILING(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5142 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5143 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5144 if (opt_junk && size < oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5145 memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5146 - size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5147 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5148 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5149 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5150 if (psize < oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5151 extent_node_t *node, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5152
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5153 pages_decommit((void *)((uintptr_t)ptr + psize),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5154 oldsize - psize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5155
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5156 /* Update recorded size. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5157 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5158 key.addr = __DECONST(void *, ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5159 node = extent_tree_ad_search(&huge, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5160 assert(node != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5161 assert(node->size == oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5162 # ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5163 huge_allocated -= oldsize - psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5164 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5165 node->size = psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5166 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5167 } else if (psize > oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5168 extent_node_t *node, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5169
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5170 pages_commit((void *)((uintptr_t)ptr + oldsize),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5171 psize - oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5172
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5173 /* Update recorded size. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5174 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5175 key.addr = __DECONST(void *, ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5176 node = extent_tree_ad_search(&huge, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5177 assert(node != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5178 assert(node->size == oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5179 # ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5180 huge_allocated += psize - oldsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5181 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5182 node->size = psize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5183 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5184 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5185 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5186 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5187 if (opt_zero && size > oldsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5188 memset((void *)((uintptr_t)ptr + oldsize), 0, size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5189 - oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5190 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5191 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5192 return (ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5193 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5194
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5195 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5196 * If we get here, then size and oldsize are different enough that we
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5197 * need to use a different size class. In that case, fall back to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5198 * allocating new space and copying.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5199 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5200 ret = huge_malloc(size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5201 if (ret == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5202 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5203
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5204 copysize = (size < oldsize) ? size : oldsize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5205 #ifdef VM_COPY_MIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5206 if (copysize >= VM_COPY_MIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5207 pages_copy(ret, ptr, copysize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5208 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5209 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5210 memcpy(ret, ptr, copysize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5211 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5212 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5213 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5214
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5215 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5216 huge_dalloc(void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5217 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5218 extent_node_t *node, key;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5219
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5220 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5221
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5222 /* Extract from tree of huge allocations. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5223 key.addr = ptr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5224 node = extent_tree_ad_search(&huge, &key);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5225 assert(node != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5226 assert(node->addr == ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5227 extent_tree_ad_remove(&huge, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5228
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5229 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5230 huge_ndalloc++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5231 huge_allocated -= node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5232 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5233
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5234 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5235
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5236 /* Unmap chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5237 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5238 if (opt_junk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5239 memset(node->addr, 0x5a, node->size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5240 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5241 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5242 chunk_dealloc(node->addr, CHUNK_CEILING(node->size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5243 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5244 chunk_dealloc(node->addr, node->size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5245 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5246 VALGRIND_FREELIKE_BLOCK(node->addr, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5247
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5248 base_node_dealloc(node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5249 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5250
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5251 #ifdef MOZ_MEMORY_BSD
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5252 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5253 malloc_ncpus(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5254 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5255 unsigned ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5256 int mib[2];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5257 size_t len;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5258
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5259 mib[0] = CTL_HW;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5260 mib[1] = HW_NCPU;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5261 len = sizeof(ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5262 if (sysctl(mib, 2, &ret, &len, (void *) 0, 0) == -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5263 /* Error. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5264 return (1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5265 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5266
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5267 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5268 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5269 #elif (defined(MOZ_MEMORY_LINUX))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5270 #include <fcntl.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5271
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5272 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5273 malloc_ncpus(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5274 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5275 unsigned ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5276 int fd, nread, column;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5277 char buf[1024];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5278 static const char matchstr[] = "processor\t:";
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5279 int i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5280
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5281 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5282 * sysconf(3) would be the preferred method for determining the number
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5283 * of CPUs, but it uses malloc internally, which causes untennable
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5284 * recursion during malloc initialization.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5285 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5286 fd = open("/proc/cpuinfo", O_RDONLY);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5287 if (fd == -1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5288 return (1); /* Error. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5289 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5290 * Count the number of occurrences of matchstr at the beginnings of
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5291 * lines. This treats hyperthreaded CPUs as multiple processors.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5292 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5293 column = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5294 ret = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5295 while (true) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5296 nread = read(fd, &buf, sizeof(buf));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5297 if (nread <= 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5298 break; /* EOF or error. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5299 for (i = 0;i < nread;i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5300 char c = buf[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5301 if (c == '\n')
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5302 column = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5303 else if (column != -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5304 if (c == matchstr[column]) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5305 column++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5306 if (column == sizeof(matchstr) - 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5307 column = -1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5308 ret++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5309 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5310 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5311 column = -1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5312 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5313 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5314 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5315
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5316 if (ret == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5317 ret = 1; /* Something went wrong in the parser. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5318 close(fd);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5319
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5320 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5321 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5322 #elif (defined(MOZ_MEMORY_DARWIN))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5323 #include <mach/mach_init.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5324 #include <mach/mach_host.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5325
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5326 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5327 malloc_ncpus(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5328 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5329 kern_return_t error;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5330 natural_t n;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5331 processor_info_array_t pinfo;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5332 mach_msg_type_number_t pinfocnt;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5333
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5334 error = host_processor_info(mach_host_self(), PROCESSOR_BASIC_INFO,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5335 &n, &pinfo, &pinfocnt);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5336 if (error != KERN_SUCCESS)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5337 return (1); /* Error. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5338 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5339 return (n);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5340 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5341 #elif (defined(MOZ_MEMORY_SOLARIS))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5342
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5343 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5344 malloc_ncpus(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5345 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5346 return sysconf(_SC_NPROCESSORS_ONLN);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5347 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5348 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5349 static inline unsigned
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5350 malloc_ncpus(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5351 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5352
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5353 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5354 * We lack a way to determine the number of CPUs on this platform, so
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5355 * assume 1 CPU.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5356 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5357 return (1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5358 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5359 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5360
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5361 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5362 malloc_print_stats(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5363 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5364
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5365 if (opt_print_stats) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5366 char s[UMAX2S_BUFSIZE];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5367 _malloc_message("___ Begin malloc statistics ___\n", "", "",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5368 "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5369 _malloc_message("Assertions ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5370 #ifdef NDEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5371 "disabled",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5372 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5373 "enabled",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5374 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5375 "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5376 _malloc_message("Boolean MALLOC_OPTIONS: ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5377 opt_abort ? "A" : "a", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5378 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5379 _malloc_message(opt_junk ? "J" : "j", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5380 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5381 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5382 _malloc_message(opt_pagefile ? "o" : "O", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5383 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5384 _malloc_message("P", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5385 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5386 _malloc_message(opt_utrace ? "U" : "u", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5387 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5388 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5389 _malloc_message(opt_sysv ? "V" : "v", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5390 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5391 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5392 _malloc_message(opt_xmalloc ? "X" : "x", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5393 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5394 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5395 _malloc_message(opt_zero ? "Z" : "z", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5396 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5397 _malloc_message("\n", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5398
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5399 _malloc_message("CPUs: ", umax2s(ncpus, s), "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5400 _malloc_message("Max arenas: ", umax2s(narenas, s), "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5401 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5402 _malloc_message("Arena balance threshold: ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5403 umax2s(opt_balance_threshold, s), "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5404 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5405 _malloc_message("Pointer size: ", umax2s(sizeof(void *), s),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5406 "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5407 _malloc_message("Quantum size: ", umax2s(quantum, s), "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5408 _malloc_message("Max small size: ", umax2s(small_max, s), "\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5409 "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5410 _malloc_message("Max dirty pages per arena: ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5411 umax2s(opt_dirty_max, s), "\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5412
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5413 _malloc_message("Chunk size: ", umax2s(chunksize, s), "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5414 _malloc_message(" (2^", umax2s(opt_chunk_2pow, s), ")\n", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5415
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5416 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5417 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5418 size_t allocated, mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5419 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5420 uint64_t nbalance = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5421 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5422 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5423 arena_t *arena;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5424
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5425 /* Calculate and print allocated/mapped stats. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5426
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5427 /* arenas. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5428 for (i = 0, allocated = 0; i < narenas; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5429 if (arenas[i] != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5430 malloc_spin_lock(&arenas[i]->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5431 allocated +=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5432 arenas[i]->stats.allocated_small;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5433 allocated +=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5434 arenas[i]->stats.allocated_large;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5435 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5436 nbalance += arenas[i]->stats.nbalance;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5437 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5438 malloc_spin_unlock(&arenas[i]->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5439 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5440 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5441
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5442 /* huge/base. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5443 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5444 allocated += huge_allocated;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5445 mapped = stats_chunks.curchunks * chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5446 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5447
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5448 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5449 mapped += base_mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5450 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5451
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5452 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5453 malloc_printf("Allocated: %lu, mapped: %lu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5454 allocated, mapped);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5455 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5456 malloc_printf("Allocated: %zu, mapped: %zu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5457 allocated, mapped);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5458 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5459
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5460 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5461 malloc_printf("Reserve: min "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5462 "cur max\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5463 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5464 malloc_printf(" %12lu %12lu %12lu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5465 CHUNK_CEILING(reserve_min) >> opt_chunk_2pow,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5466 reserve_cur >> opt_chunk_2pow,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5467 reserve_max >> opt_chunk_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5468 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5469 malloc_printf(" %12zu %12zu %12zu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5470 CHUNK_CEILING(reserve_min) >> opt_chunk_2pow,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5471 reserve_cur >> opt_chunk_2pow,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5472 reserve_max >> opt_chunk_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5473 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5474 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5475
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5476 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5477 malloc_printf("Arena balance reassignments: %llu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5478 nbalance);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5479 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5480
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5481 /* Print chunk stats. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5482 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5483 chunk_stats_t chunks_stats;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5484
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5485 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5486 chunks_stats = stats_chunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5487 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5488
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5489 malloc_printf("chunks: nchunks "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5490 "highchunks curchunks\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5491 malloc_printf(" %13llu%13lu%13lu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5492 chunks_stats.nchunks,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5493 chunks_stats.highchunks,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5494 chunks_stats.curchunks);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5495 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5496
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5497 /* Print chunk stats. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5498 malloc_printf(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5499 "huge: nmalloc ndalloc allocated\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5500 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5501 malloc_printf(" %12llu %12llu %12lu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5502 huge_nmalloc, huge_ndalloc, huge_allocated);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5503 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5504 malloc_printf(" %12llu %12llu %12zu\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5505 huge_nmalloc, huge_ndalloc, huge_allocated);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5506 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5507 /* Print stats for each arena. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5508 for (i = 0; i < narenas; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5509 arena = arenas[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5510 if (arena != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5511 malloc_printf(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5512 "\narenas[%u]:\n", i);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5513 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5514 stats_print(arena);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5515 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5516 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5517 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5518 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5519 #endif /* #ifdef MALLOC_STATS */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5520 _malloc_message("--- End malloc statistics ---\n", "", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5521 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5522 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5523
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5524 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5525 * FreeBSD's pthreads implementation calls malloc(3), so the malloc
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5526 * implementation has to take pains to avoid infinite recursion during
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5527 * initialization.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5528 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5529 #if (defined(MOZ_MEMORY_WINDOWS) || defined(MOZ_MEMORY_DARWIN)) && !defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5530 #define malloc_init() false
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5531 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5532 static inline bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5533 malloc_init(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5534 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5535
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5536 if (malloc_initialized == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5537 return (malloc_init_hard());
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5538
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5539 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5540 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5541 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5542
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5543 #if !defined(MOZ_MEMORY_WINDOWS) || defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5544 static
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5545 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5546 bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5547 malloc_init_hard(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5548 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5549 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5550 char buf[PATH_MAX + 1];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5551 const char *opts;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5552 long result;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5553 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5554 int linklen;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5555 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5556
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5557 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5558 malloc_mutex_lock(&init_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5559 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5560
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5561 if (malloc_initialized) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5562 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5563 * Another thread initialized the allocator before this one
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5564 * acquired init_lock.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5565 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5566 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5567 malloc_mutex_unlock(&init_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5568 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5569 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5570 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5571
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5572 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5573 /* get a thread local storage index */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5574 tlsIndex = TlsAlloc();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5575 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5576
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5577 /* Get page size and number of CPUs */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5578 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5579 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5580 SYSTEM_INFO info;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5581
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5582 GetSystemInfo(&info);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5583 result = info.dwPageSize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5584
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5585 pagesize = (unsigned) result;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5586
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5587 ncpus = info.dwNumberOfProcessors;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5588 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5589 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5590 ncpus = malloc_ncpus();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5591
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5592 result = sysconf(_SC_PAGESIZE);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5593 assert(result != -1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5594
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5595 pagesize = (unsigned) result;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5596 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5597
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5598 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5599 * We assume that pagesize is a power of 2 when calculating
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5600 * pagesize_mask and pagesize_2pow.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5601 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5602 assert(((result - 1) & result) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5603 pagesize_mask = result - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5604 pagesize_2pow = ffs((int)result) - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5605
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5606 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5607 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5608 * Determine where to create page files. It is insufficient to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5609 * unconditionally use P_tmpdir (typically "/tmp"), since for some
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5610 * operating systems /tmp is a separate filesystem that is rather small.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5611 * Therefore prefer, in order, the following locations:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5612 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5613 * 1) MALLOC_TMPDIR
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5614 * 2) TMPDIR
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5615 * 3) P_tmpdir
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5616 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5617 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5618 char *s;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5619 size_t slen;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5620 static const char suffix[] = "/jemalloc.XXXXXX";
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5621
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5622 if ((s = getenv("MALLOC_TMPDIR")) == NULL && (s =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5623 getenv("TMPDIR")) == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5624 s = P_tmpdir;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5625 slen = strlen(s);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5626 if (slen + sizeof(suffix) > sizeof(pagefile_templ)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5627 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5628 ": (malloc) Page file path too long\n",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5629 "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5630 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5631 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5632 memcpy(pagefile_templ, s, slen);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5633 memcpy(&pagefile_templ[slen], suffix, sizeof(suffix));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5634 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5635 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5636
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5637 for (i = 0; i < 3; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5638 unsigned j;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5639
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5640 /* Get runtime configuration. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5641 switch (i) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5642 case 0:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5643 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5644 if ((linklen = readlink("/etc/malloc.conf", buf,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5645 sizeof(buf) - 1)) != -1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5646 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5647 * Use the contents of the "/etc/malloc.conf"
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5648 * symbolic link's name.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5649 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5650 buf[linklen] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5651 opts = buf;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5652 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5653 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5654 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5655 /* No configuration specified. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5656 buf[0] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5657 opts = buf;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5658 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5659 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5660 case 1:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5661 if (issetugid() == 0 && (opts =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5662 getenv("MALLOC_OPTIONS")) != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5663 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5664 * Do nothing; opts is already initialized to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5665 * the value of the MALLOC_OPTIONS environment
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5666 * variable.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5667 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5668 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5669 /* No configuration specified. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5670 buf[0] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5671 opts = buf;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5672 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5673 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5674 case 2:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5675 if (_malloc_options != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5676 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5677 * Use options that were compiled into the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5678 * program.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5679 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5680 opts = _malloc_options;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5681 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5682 /* No configuration specified. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5683 buf[0] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5684 opts = buf;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5685 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5686 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5687 default:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5688 /* NOTREACHED */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5689 buf[0] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5690 opts = buf;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5691 assert(false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5692 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5693
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5694 for (j = 0; opts[j] != '\0'; j++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5695 unsigned k, nreps;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5696 bool nseen;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5697
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5698 /* Parse repetition count, if any. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5699 for (nreps = 0, nseen = false;; j++, nseen = true) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5700 switch (opts[j]) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5701 case '0': case '1': case '2': case '3':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5702 case '4': case '5': case '6': case '7':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5703 case '8': case '9':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5704 nreps *= 10;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5705 nreps += opts[j] - '0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5706 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5707 default:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5708 goto MALLOC_OUT;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5709 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5710 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5711 MALLOC_OUT:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5712 if (nseen == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5713 nreps = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5714
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5715 for (k = 0; k < nreps; k++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5716 switch (opts[j]) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5717 case 'a':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5718 opt_abort = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5719 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5720 case 'A':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5721 opt_abort = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5722 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5723 case 'b':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5724 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5725 opt_balance_threshold >>= 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5726 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5727 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5728 case 'B':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5729 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5730 if (opt_balance_threshold == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5731 opt_balance_threshold = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5732 else if ((opt_balance_threshold << 1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5733 > opt_balance_threshold)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5734 opt_balance_threshold <<= 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5735 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5736 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5737 case 'f':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5738 opt_dirty_max >>= 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5739 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5740 case 'F':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5741 if (opt_dirty_max == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5742 opt_dirty_max = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5743 else if ((opt_dirty_max << 1) != 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5744 opt_dirty_max <<= 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5745 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5746 case 'g':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5747 opt_reserve_range_lshift--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5748 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5749 case 'G':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5750 opt_reserve_range_lshift++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5751 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5752 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5753 case 'j':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5754 opt_junk = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5755 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5756 case 'J':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5757 opt_junk = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5758 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5759 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5760 case 'k':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5761 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5762 * Chunks always require at least one
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5763 * header page, so chunks can never be
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5764 * smaller than two pages.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5765 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5766 if (opt_chunk_2pow > pagesize_2pow + 1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5767 opt_chunk_2pow--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5768 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5769 case 'K':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5770 if (opt_chunk_2pow + 1 <
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5771 (sizeof(size_t) << 3))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5772 opt_chunk_2pow++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5773 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5774 case 'n':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5775 opt_narenas_lshift--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5776 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5777 case 'N':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5778 opt_narenas_lshift++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5779 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5780 #ifdef MALLOC_PAGEFILE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5781 case 'o':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5782 /* Do not over-commit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5783 opt_pagefile = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5784 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5785 case 'O':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5786 /* Allow over-commit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5787 opt_pagefile = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5788 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5789 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5790 case 'p':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5791 opt_print_stats = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5792 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5793 case 'P':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5794 opt_print_stats = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5795 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5796 case 'q':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5797 if (opt_quantum_2pow > QUANTUM_2POW_MIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5798 opt_quantum_2pow--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5799 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5800 case 'Q':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5801 if (opt_quantum_2pow < pagesize_2pow -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5802 1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5803 opt_quantum_2pow++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5804 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5805 case 'r':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5806 opt_reserve_min_lshift--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5807 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5808 case 'R':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5809 opt_reserve_min_lshift++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5810 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5811 case 's':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5812 if (opt_small_max_2pow >
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5813 QUANTUM_2POW_MIN)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5814 opt_small_max_2pow--;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5815 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5816 case 'S':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5817 if (opt_small_max_2pow < pagesize_2pow
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5818 - 1)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5819 opt_small_max_2pow++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5820 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5821 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5822 case 'u':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5823 opt_utrace = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5824 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5825 case 'U':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5826 opt_utrace = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5827 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5828 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5829 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5830 case 'v':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5831 opt_sysv = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5832 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5833 case 'V':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5834 opt_sysv = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5835 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5836 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5837 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5838 case 'x':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5839 opt_xmalloc = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5840 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5841 case 'X':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5842 opt_xmalloc = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5843 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5844 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5845 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5846 case 'z':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5847 opt_zero = false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5848 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5849 case 'Z':
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5850 opt_zero = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5851 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5852 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5853 default: {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5854 char cbuf[2];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5855
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5856 cbuf[0] = opts[j];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5857 cbuf[1] = '\0';
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5858 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5859 ": (malloc) Unsupported character "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5860 "in malloc options: '", cbuf,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5861 "'\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5862 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5863 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5864 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5865 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5866 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5867
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5868 /* Take care to call atexit() only once. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5869 if (opt_print_stats) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5870 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5871 /* Print statistics at exit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5872 atexit(malloc_print_stats);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5873 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5874 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5875
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5876 #if (!defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5877 /* Prevent potential deadlock on malloc locks after fork. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5878 pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5879 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5880
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5881 /* Set variables according to the value of opt_small_max_2pow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5882 if (opt_small_max_2pow < opt_quantum_2pow)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5883 opt_small_max_2pow = opt_quantum_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5884 small_max = (1U << opt_small_max_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5885
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5886 /* Set bin-related variables. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5887 bin_maxclass = (pagesize >> 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5888 assert(opt_quantum_2pow >= TINY_MIN_2POW);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5889 ntbins = opt_quantum_2pow - TINY_MIN_2POW;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5890 assert(ntbins <= opt_quantum_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5891 nqbins = (small_max >> opt_quantum_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5892 nsbins = pagesize_2pow - opt_small_max_2pow - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5893
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5894 /* Set variables according to the value of opt_quantum_2pow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5895 quantum = (1U << opt_quantum_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5896 quantum_mask = quantum - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5897 if (ntbins > 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5898 small_min = (quantum >> 1) + 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5899 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5900 small_min = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5901 assert(small_min <= quantum);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5902
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5903 /* Set variables according to the value of opt_chunk_2pow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5904 chunksize = (1LU << opt_chunk_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5905 chunksize_mask = chunksize - 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5906 chunk_npages = (chunksize >> pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5907 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5908 size_t header_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5909
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5910 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5911 * Compute the header size such that it is large
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5912 * enough to contain the page map and enough nodes for the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5913 * worst case: one node per non-header page plus one extra for
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5914 * situations where we briefly have one more node allocated
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5915 * than we will need.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5916 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5917 header_size = sizeof(arena_chunk_t) +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5918 (sizeof(arena_chunk_map_t) * (chunk_npages - 1));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5919 arena_chunk_header_npages = (header_size >> pagesize_2pow) +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5920 ((header_size & pagesize_mask) != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5921 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5922 arena_maxclass = chunksize - (arena_chunk_header_npages <<
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5923 pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5924
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5925 #ifdef JEMALLOC_USES_MAP_ALIGN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5926 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5927 * When using MAP_ALIGN, the alignment parameter must be a power of two
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5928 * multiple of the system pagesize, or mmap will fail.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5929 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5930 assert((chunksize % pagesize) == 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5931 assert((1 << (ffs(chunksize / pagesize) - 1)) == (chunksize/pagesize));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5932 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5933
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5934 UTRACE(0, 0, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5935
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5936 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5937 memset(&stats_chunks, 0, sizeof(chunk_stats_t));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5938 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5939
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5940 /* Various sanity checks that regard configuration. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5941 assert(quantum >= sizeof(void *));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5942 assert(quantum <= pagesize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5943 assert(chunksize >= pagesize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5944 assert(quantum * 4 <= chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5945
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5946 /* Initialize chunks data. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5947 malloc_mutex_init(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5948 extent_tree_ad_new(&huge);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5949 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5950 huge_nmalloc = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5951 huge_ndalloc = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5952 huge_allocated = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5953 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5954
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5955 /* Initialize base allocation data structures. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5956 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5957 base_mapped = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5958 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5959 base_nodes = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5960 base_reserve_regs = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5961 malloc_mutex_init(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5962
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5963 #ifdef MOZ_MEMORY_NARENAS_DEFAULT_ONE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5964 narenas = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5965 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5966 if (ncpus > 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5967 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5968 * For SMP systems, create four times as many arenas as there
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5969 * are CPUs by default.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5970 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5971 opt_narenas_lshift += 2;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5972 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5973
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5974 /* Determine how many arenas to use. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5975 narenas = ncpus;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5976 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5977 if (opt_narenas_lshift > 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5978 if ((narenas << opt_narenas_lshift) > narenas)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5979 narenas <<= opt_narenas_lshift;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5980 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5981 * Make sure not to exceed the limits of what base_alloc() can
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5982 * handle.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5983 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5984 if (narenas * sizeof(arena_t *) > chunksize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5985 narenas = chunksize / sizeof(arena_t *);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5986 } else if (opt_narenas_lshift < 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5987 if ((narenas >> -opt_narenas_lshift) < narenas)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5988 narenas >>= -opt_narenas_lshift;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5989 /* Make sure there is at least one arena. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5990 if (narenas == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5991 narenas = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5992 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5993 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5994 assert(narenas != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5995 for (narenas_2pow = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5996 (narenas >> (narenas_2pow + 1)) != 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5997 narenas_2pow++);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5998 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
5999
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6000 #ifdef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6001 if (narenas > 1) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6002 static const unsigned primes[] = {1, 3, 5, 7, 11, 13, 17, 19,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6003 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6004 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6005 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6006 223, 227, 229, 233, 239, 241, 251, 257, 263};
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6007 unsigned nprimes, parenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6008
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6009 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6010 * Pick a prime number of hash arenas that is more than narenas
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6011 * so that direct hashing of pthread_self() pointers tends to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6012 * spread allocations evenly among the arenas.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6013 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6014 assert((narenas & 1) == 0); /* narenas must be even. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6015 nprimes = (sizeof(primes) >> SIZEOF_INT_2POW);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6016 parenas = primes[nprimes - 1]; /* In case not enough primes. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6017 for (i = 1; i < nprimes; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6018 if (primes[i] > narenas) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6019 parenas = primes[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6020 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6021 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6022 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6023 narenas = parenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6024 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6025 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6026
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6027 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6028 # ifndef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6029 next_arena = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6030 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6031 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6032
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6033 /* Allocate and initialize arenas. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6034 arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6035 if (arenas == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6036 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6037 malloc_mutex_unlock(&init_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6038 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6039 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6040 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6041 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6042 * Zero the array. In practice, this should always be pre-zeroed,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6043 * since it was just mmap()ed, but let's be sure.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6044 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6045 memset(arenas, 0, sizeof(arena_t *) * narenas);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6046
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6047 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6048 * Initialize one arena here. The rest are lazily created in
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6049 * choose_arena_hard().
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6050 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6051 arenas_extend(0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6052 if (arenas[0] == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6053 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6054 malloc_mutex_unlock(&init_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6055 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6056 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6057 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6058 #ifndef NO_TLS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6059 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6060 * Assign the initial arena to the initial thread, in order to avoid
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6061 * spurious creation of an extra arena if the application switches to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6062 * threaded mode.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6063 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6064 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6065 TlsSetValue(tlsIndex, arenas[0]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6066 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6067 arenas_map = arenas[0];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6068 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6069 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6070
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6071 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6072 * Seed here for the initial thread, since choose_arena_hard() is only
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6073 * called for other threads. The seed value doesn't really matter.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6074 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6075 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6076 SPRN(balance, 42);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6077 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6078
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6079 malloc_spin_init(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6080
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6081 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6082 chunk_rtree = malloc_rtree_new((SIZEOF_PTR << 3) - opt_chunk_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6083 if (chunk_rtree == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6084 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6085 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6086
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6087 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6088 * Configure and initialize the memory reserve. This needs to happen
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6089 * late during initialization, since chunks are allocated.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6090 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6091 malloc_mutex_init(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6092 reserve_min = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6093 reserve_cur = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6094 reserve_max = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6095 if (RESERVE_RANGE_2POW_DEFAULT + opt_reserve_range_lshift >= 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6096 reserve_max += chunksize << (RESERVE_RANGE_2POW_DEFAULT +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6097 opt_reserve_range_lshift);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6098 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6099 ql_new(&reserve_regs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6100 reserve_seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6101 extent_tree_szad_new(&reserve_chunks_szad);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6102 extent_tree_ad_new(&reserve_chunks_ad);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6103 if (RESERVE_MIN_2POW_DEFAULT + opt_reserve_min_lshift >= 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6104 reserve_min_set(chunksize << (RESERVE_MIN_2POW_DEFAULT +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6105 opt_reserve_min_lshift));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6106 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6107
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6108 malloc_initialized = true;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6109 #ifndef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6110 malloc_mutex_unlock(&init_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6111 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6112 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6113 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6114
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6115 /* XXX Why not just expose malloc_print_stats()? */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6116 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6117 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6118 malloc_shutdown()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6119 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6120
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6121 malloc_print_stats();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6122 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6123 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6124
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6125 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6126 * End general internal functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6127 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6128 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6129 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6130 * Begin malloc(3)-compatible functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6131 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6132
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6133 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6134 * Inline the standard malloc functions if they are being subsumed by Darwin's
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6135 * zone infrastructure.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6136 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6137 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6138 # define ZONE_INLINE inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6139 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6140 # define ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6141 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6142
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6143 /* Mangle standard interfaces on Darwin and Windows CE,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6144 in order to avoid linking problems. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6145 #if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_WINCE)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6146 #define malloc(a) moz_malloc(a)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6147 #define valloc(a) moz_valloc(a)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6148 #define calloc(a, b) moz_calloc(a, b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6149 #define realloc(a, b) moz_realloc(a, b)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6150 #define free(a) moz_free(a)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6151 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6152
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6153 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6154 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6155 malloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6156 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6157 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6158
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6159 if (malloc_init()) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6160 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6161 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6162 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6163
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6164 if (size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6165 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6166 if (opt_sysv == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6167 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6168 size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6169 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6170 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6171 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6172 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6173 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6174 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6175 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6176
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6177 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6178
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6179 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6180 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6181 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6182 if (opt_xmalloc) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6183 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6184 ": (malloc) Error in malloc(): out of memory\n", "",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6185 "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6186 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6187 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6188 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6189 errno = ENOMEM;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6190 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6191
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6192 UTRACE(0, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6193 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6194 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6195
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6196 #ifdef MOZ_MEMORY_SOLARIS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6197 # ifdef __SUNPRO_C
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6198 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6199 memalign(size_t alignment, size_t size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6200 #pragma no_inline(memalign)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6201 # elif (defined(__GNU_C__))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6202 __attribute__((noinline))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6203 # endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6204 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6205 inline
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6206 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6207 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6208 memalign(size_t alignment, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6209 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6210 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6211
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6212 assert(((alignment - 1) & alignment) == 0 && alignment >=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6213 sizeof(void *));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6214
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6215 if (malloc_init()) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6216 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6217 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6218 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6219
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6220 ret = ipalloc(alignment, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6221
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6222 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6223 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6224 if (opt_xmalloc && ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6225 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6226 ": (malloc) Error in memalign(): out of memory\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6227 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6228 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6229 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6230 UTRACE(0, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6231 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6232 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6233
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6234 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6235 int
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6236 posix_memalign(void **memptr, size_t alignment, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6237 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6238 void *result;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6239
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6240 /* Make sure that alignment is a large enough power of 2. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6241 if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6242 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6243 if (opt_xmalloc) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6244 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6245 ": (malloc) Error in posix_memalign(): "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6246 "invalid alignment\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6247 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6248 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6249 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6250 return (EINVAL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6251 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6252
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6253 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6254 result = moz_memalign(alignment, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6255 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6256 result = memalign(alignment, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6257 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6258 if (result == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6259 return (ENOMEM);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6260
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6261 *memptr = result;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6262 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6263 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6264
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6265 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6266 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6267 valloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6268 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6269 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6270 return (moz_memalign(pagesize, size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6271 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6272 return (memalign(pagesize, size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6273 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6274 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6275
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6276 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6277 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6278 calloc(size_t num, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6279 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6280 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6281 size_t num_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6282
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6283 if (malloc_init()) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6284 num_size = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6285 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6286 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6287 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6288
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6289 num_size = num * size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6290 if (num_size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6291 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6292 if ((opt_sysv == false) && ((num == 0) || (size == 0)))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6293 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6294 num_size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6295 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6296 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6297 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6298 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6299 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6300 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6301 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6302 * Try to avoid division here. We know that it isn't possible to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6303 * overflow during multiplication if neither operand uses any of the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6304 * most significant half of the bits in a size_t.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6305 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6306 } else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6307 && (num_size / size != num)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6308 /* size_t overflow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6309 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6310 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6311 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6312
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6313 ret = icalloc(num_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6314
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6315 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6316 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6317 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6318 if (opt_xmalloc) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6319 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6320 ": (malloc) Error in calloc(): out of memory\n", "",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6321 "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6322 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6323 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6324 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6325 errno = ENOMEM;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6326 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6327
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6328 UTRACE(0, num_size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6329 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6330 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6331
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6332 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6333 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6334 realloc(void *ptr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6335 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6336 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6337
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6338 if (size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6339 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6340 if (opt_sysv == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6341 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6342 size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6343 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6344 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6345 if (ptr != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6346 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6347 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6348 goto RETURN;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6349 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6350 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6351 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6352
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6353 if (ptr != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6354 assert(malloc_initialized);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6355
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6356 ret = iralloc(ptr, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6357
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6358 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6359 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6360 if (opt_xmalloc) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6361 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6362 ": (malloc) Error in realloc(): out of "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6363 "memory\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6364 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6365 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6366 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6367 errno = ENOMEM;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6368 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6369 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6370 if (malloc_init())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6371 ret = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6372 else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6373 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6374
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6375 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6376 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6377 if (opt_xmalloc) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6378 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6379 ": (malloc) Error in realloc(): out of "
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6380 "memory\n", "", "");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6381 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6382 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6383 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6384 errno = ENOMEM;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6385 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6386 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6387
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6388 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6389 RETURN:
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6390 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6391 UTRACE(ptr, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6392 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6393 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6394
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6395 ZONE_INLINE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6396 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6397 free(void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6398 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6399
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6400 UTRACE(ptr, 0, 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6401 if (ptr != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6402 assert(malloc_initialized);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6403
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6404 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6405 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6406 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6407
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6408 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6409 * End malloc(3)-compatible functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6410 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6411 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6412 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6413 * Begin non-standard functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6414 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6415
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6416 size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6417 malloc_usable_size(const void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6418 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6419
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6420 #ifdef MALLOC_VALIDATE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6421 return (isalloc_validate(ptr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6422 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6423 assert(ptr != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6424
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6425 return (isalloc(ptr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6426 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6427 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6428
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6429 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6430 jemalloc_stats(jemalloc_stats_t *stats)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6431 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6432 size_t i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6433
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6434 assert(stats != NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6435
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6436 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6437 * Gather runtime settings.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6438 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6439 stats->opt_abort = opt_abort;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6440 stats->opt_junk =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6441 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6442 opt_junk ? true :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6443 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6444 false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6445 stats->opt_utrace =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6446 #ifdef MALLOC_UTRACE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6447 opt_utrace ? true :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6448 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6449 false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6450 stats->opt_sysv =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6451 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6452 opt_sysv ? true :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6453 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6454 false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6455 stats->opt_xmalloc =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6456 #ifdef MALLOC_XMALLOC
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6457 opt_xmalloc ? true :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6458 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6459 false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6460 stats->opt_zero =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6461 #ifdef MALLOC_FILL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6462 opt_zero ? true :
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6463 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6464 false;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6465 stats->narenas = narenas;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6466 stats->balance_threshold =
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6467 #ifdef MALLOC_BALANCE
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6468 opt_balance_threshold
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6469 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6470 SIZE_T_MAX
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6471 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6472 ;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6473 stats->quantum = quantum;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6474 stats->small_max = small_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6475 stats->large_max = arena_maxclass;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6476 stats->chunksize = chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6477 stats->dirty_max = opt_dirty_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6478
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6479 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6480 stats->reserve_min = reserve_min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6481 stats->reserve_max = reserve_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6482 stats->reserve_cur = reserve_cur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6483 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6484
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6485 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6486 * Gather current memory usage statistics.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6487 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6488 stats->mapped = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6489 stats->committed = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6490 stats->allocated = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6491 stats->dirty = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6492
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6493 /* Get huge mapped/allocated. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6494 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6495 stats->mapped += stats_chunks.curchunks * chunksize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6496 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6497 stats->committed += huge_allocated;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6498 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6499 stats->allocated += huge_allocated;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6500 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6501
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6502 /* Get base mapped. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6503 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6504 stats->mapped += base_mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6505 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6506 stats->committed += base_mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6507 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6508 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6509
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6510 /* Iterate over arenas and their chunks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6511 for (i = 0; i < narenas; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6512 arena_t *arena = arenas[i];
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6513 if (arena != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6514 arena_chunk_t *chunk;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6515
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6516 malloc_spin_lock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6517 stats->allocated += arena->stats.allocated_small;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6518 stats->allocated += arena->stats.allocated_large;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6519 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6520 rb_foreach_begin(arena_chunk_t, link_dirty,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6521 &arena->chunks_dirty, chunk) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6522 size_t j;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6523
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6524 for (j = 0; j < chunk_npages; j++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6525 if ((chunk->map[j].bits &
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6526 CHUNK_MAP_DECOMMITTED) == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6527 stats->committed += pagesize;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6528 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6529 } rb_foreach_end(arena_chunk_t, link_dirty,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6530 &arena->chunks_dirty, chunk)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6531 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6532 stats->dirty += (arena->ndirty << pagesize_2pow);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6533 malloc_spin_unlock(&arena->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6534 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6535 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6536
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6537 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6538 stats->committed = stats->mapped;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6539 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6540 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6541
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6542 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6543 xmalloc(size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6544 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6545 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6546
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6547 if (malloc_init())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6548 reserve_fail(size, "xmalloc");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6549
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6550 if (size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6551 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6552 if (opt_sysv == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6553 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6554 size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6555 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6556 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6557 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6558 ": (malloc) Error in xmalloc(): ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6559 "invalid size 0", "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6560 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6561 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6562 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6563 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6564
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6565 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6566 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6567 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6568
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6569 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6570 seq = reserve_crit(size, "xmalloc", seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6571 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6572 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6573 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6574
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6575 UTRACE(0, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6576 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6577 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6578
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6579 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6580 xcalloc(size_t num, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6581 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6582 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6583 size_t num_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6584
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6585 num_size = num * size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6586 if (malloc_init())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6587 reserve_fail(num_size, "xcalloc");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6588
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6589 if (num_size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6590 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6591 if ((opt_sysv == false) && ((num == 0) || (size == 0)))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6592 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6593 num_size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6594 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6595 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6596 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6597 ": (malloc) Error in xcalloc(): ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6598 "invalid size 0", "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6599 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6600 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6601 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6602 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6603 * Try to avoid division here. We know that it isn't possible to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6604 * overflow during multiplication if neither operand uses any of the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6605 * most significant half of the bits in a size_t.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6606 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6607 } else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6608 && (num_size / size != num)) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6609 /* size_t overflow. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6610 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6611 ": (malloc) Error in xcalloc(): ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6612 "size overflow", "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6613 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6614 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6615
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6616 ret = icalloc(num_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6617 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6618 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6619
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6620 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6621 seq = reserve_crit(num_size, "xcalloc", seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6622 ret = icalloc(num_size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6623 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6624 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6625
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6626 UTRACE(0, num_size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6627 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6628 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6629
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6630 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6631 xrealloc(void *ptr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6632 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6633 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6634
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6635 if (size == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6636 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6637 if (opt_sysv == false)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6638 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6639 size = 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6640 #ifdef MALLOC_SYSV
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6641 else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6642 if (ptr != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6643 idalloc(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6644 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6645 ": (malloc) Error in xrealloc(): ",
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6646 "invalid size 0", "\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6647 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6648 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6649 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6650 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6651
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6652 if (ptr != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6653 assert(malloc_initialized);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6654
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6655 ret = iralloc(ptr, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6656 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6657 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6658
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6659 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6660 seq = reserve_crit(size, "xrealloc", seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6661 ret = iralloc(ptr, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6662 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6663 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6664 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6665 if (malloc_init())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6666 reserve_fail(size, "xrealloc");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6667
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6668 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6669 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6670 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6671
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6672 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6673 seq = reserve_crit(size, "xrealloc", seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6674 ret = imalloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6675 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6676 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6677 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6678
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6679 UTRACE(ptr, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6680 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6681 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6682
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6683 void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6684 xmemalign(size_t alignment, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6685 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6686 void *ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6687
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6688 assert(((alignment - 1) & alignment) == 0 && alignment >=
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6689 sizeof(void *));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6690
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6691 if (malloc_init())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6692 reserve_fail(size, "xmemalign");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6693
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6694 ret = ipalloc(alignment, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6695 if (ret == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6696 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6697
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6698 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6699 seq = reserve_crit(size, "xmemalign", seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6700 ret = ipalloc(alignment, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6701 } while (ret == NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6702 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6703
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6704 UTRACE(0, size, ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6705 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6706 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6707
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6708 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6709 reserve_shrink(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6710 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6711 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6712
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6713 assert(reserve_cur > reserve_max);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6714 #ifdef MALLOC_DEBUG
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6715 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6716 extent_node_t *node;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6717 size_t reserve_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6718
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6719 reserve_size = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6720 rb_foreach_begin(extent_node_t, link_szad, &reserve_chunks_szad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6721 node) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6722 reserve_size += node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6723 } rb_foreach_end(extent_node_t, link_szad, &reserve_chunks_szad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6724 node)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6725 assert(reserve_size == reserve_cur);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6726
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6727 reserve_size = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6728 rb_foreach_begin(extent_node_t, link_ad, &reserve_chunks_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6729 node) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6730 reserve_size += node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6731 } rb_foreach_end(extent_node_t, link_ad, &reserve_chunks_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6732 node)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6733 assert(reserve_size == reserve_cur);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6734 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6735 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6736
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6737 /* Discard chunks until the the reserve is below the size limit. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6738 rb_foreach_reverse_begin(extent_node_t, link_ad, &reserve_chunks_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6739 node) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6740 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6741 if (node->size <= reserve_cur - reserve_max) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6742 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6743 extent_node_t *tnode = extent_tree_ad_prev(
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6744 &reserve_chunks_ad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6745
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6746 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6747 assert(node->size <= reserve_cur - reserve_max);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6748 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6749
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6750 /* Discard the entire [multi-]chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6751 extent_tree_szad_remove(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6752 extent_tree_ad_remove(&reserve_chunks_ad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6753 reserve_cur -= node->size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6754 pages_unmap(node->addr, node->size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6755 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6756 stats_chunks.curchunks -= (node->size / chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6757 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6758 base_node_dealloc(node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6759 if (reserve_cur == reserve_max)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6760 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6761
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6762 rb_foreach_reverse_prev(extent_node_t, link_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6763 extent_ad_comp, &reserve_chunks_ad, tnode);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6764 #ifndef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6765 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6766 /* Discard the end of the multi-chunk. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6767 extent_tree_szad_remove(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6768 node->size -= reserve_cur - reserve_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6769 extent_tree_szad_insert(&reserve_chunks_szad, node);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6770 pages_unmap((void *)((uintptr_t)node->addr +
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6771 node->size), reserve_cur - reserve_max);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6772 #ifdef MALLOC_STATS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6773 stats_chunks.curchunks -= ((reserve_cur - reserve_max) /
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6774 chunksize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6775 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6776 reserve_cur = reserve_max;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6777 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6778 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6779 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6780 assert(reserve_cur > reserve_max);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6781 } rb_foreach_reverse_end(extent_node_t, link_ad, &reserve_chunks_ad,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6782 node)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6783 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6784
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6785 /* Send a condition notification. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6786 static uint64_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6787 reserve_notify(reserve_cnd_t cnd, size_t size, uint64_t seq)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6788 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6789 reserve_reg_t *reg;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6790
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6791 /* seq is used to keep track of distinct condition-causing events. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6792 if (seq == 0) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6793 /* Allocate new sequence number. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6794 reserve_seq++;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6795 seq = reserve_seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6796 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6797
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6798 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6799 * Advance to the next callback registration and send a notification,
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6800 * unless one has already been sent for this condition-causing event.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6801 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6802 reg = ql_first(&reserve_regs);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6803 if (reg == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6804 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6805 ql_first(&reserve_regs) = ql_next(&reserve_regs, reg, link);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6806 if (reg->seq == seq)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6807 return (0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6808 reg->seq = seq;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6809 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6810 reg->cb(reg->ctx, cnd, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6811 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6812
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6813 return (seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6814 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6815
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6816 /* Allocation failure due to OOM. Try to free some memory via callbacks. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6817 static uint64_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6818 reserve_crit(size_t size, const char *fname, uint64_t seq)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6819 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6820
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6821 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6822 * Send one condition notification. Iteration is handled by the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6823 * caller of this function.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6824 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6825 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6826 seq = reserve_notify(RESERVE_CND_CRIT, size, seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6827 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6828
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6829 /* If no notification could be sent, then no further recourse exists. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6830 if (seq == 0)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6831 reserve_fail(size, fname);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6832
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6833 return (seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6834 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6835
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6836 /* Permanent allocation failure due to OOM. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6837 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6838 reserve_fail(size_t size, const char *fname)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6839 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6840 uint64_t seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6841
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6842 /* Send fail notifications. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6843 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6844 do {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6845 seq = reserve_notify(RESERVE_CND_FAIL, size, seq);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6846 } while (seq != 0);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6847 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6848
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6849 /* Terminate the application. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6850 _malloc_message(_getprogname(),
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6851 ": (malloc) Error in ", fname, "(): out of memory\n");
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6852 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6853 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6854
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6855 bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6856 reserve_cb_register(reserve_cb_t *cb, void *ctx)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6857 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6858 reserve_reg_t *reg = base_reserve_reg_alloc();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6859 if (reg == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6860 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6861
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6862 ql_elm_new(reg, link);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6863 reg->cb = cb;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6864 reg->ctx = ctx;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6865 reg->seq = 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6866
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6867 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6868 ql_head_insert(&reserve_regs, reg, link);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6869 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6870
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6871 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6872 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6873
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6874 bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6875 reserve_cb_unregister(reserve_cb_t *cb, void *ctx)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6876 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6877 reserve_reg_t *reg = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6878
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6879 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6880 ql_foreach(reg, &reserve_regs, link) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6881 if (reg->cb == cb && reg->ctx == ctx) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6882 ql_remove(&reserve_regs, reg, link);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6883 break;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6884 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6885 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6886 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6887
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6888 if (reg != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6889 base_reserve_reg_dealloc(reg);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6890 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6891 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6892 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6893
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6894 size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6895 reserve_cur_get(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6896 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6897 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6898
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6899 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6900 ret = reserve_cur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6901 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6902
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6903 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6904 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6905
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6906 size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6907 reserve_min_get(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6908 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6909 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6910
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6911 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6912 ret = reserve_min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6913 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6914
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6915 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6916 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6917
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6918 bool
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6919 reserve_min_set(size_t min)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6920 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6921
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6922 min = CHUNK_CEILING(min);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6923
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6924 malloc_mutex_lock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6925 /* Keep |reserve_max - reserve_min| the same. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6926 if (min < reserve_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6927 reserve_max -= reserve_min - min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6928 reserve_min = min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6929 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6930 /* Protect against wrap-around. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6931 if (reserve_max + min - reserve_min < reserve_max) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6932 reserve_min = SIZE_T_MAX - (reserve_max - reserve_min)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6933 - chunksize + 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6934 reserve_max = SIZE_T_MAX - chunksize + 1;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6935 } else {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6936 reserve_max += min - reserve_min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6937 reserve_min = min;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6938 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6939 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6940
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6941 /* Resize the reserve if necessary. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6942 if (reserve_cur < reserve_min) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6943 size_t size = reserve_min - reserve_cur;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6944
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6945 /* Force the reserve to grow by allocating/deallocating. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6946 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6947 #ifdef MALLOC_DECOMMIT
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6948 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6949 void **chunks;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6950 size_t i, n;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6951
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6952 n = size >> opt_chunk_2pow;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6953 chunks = (void**)imalloc(n * sizeof(void *));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6954 if (chunks == NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6955 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6956 for (i = 0; i < n; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6957 chunks[i] = huge_malloc(chunksize, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6958 if (chunks[i] == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6959 size_t j;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6960
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6961 for (j = 0; j < i; j++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6962 huge_dalloc(chunks[j]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6963 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6964 idalloc(chunks);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6965 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6966 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6967 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6968 for (i = 0; i < n; i++)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6969 huge_dalloc(chunks[i]);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6970 idalloc(chunks);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6971 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6972 #else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6973 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6974 void *x = huge_malloc(size, false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6975 if (x == NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6976 return (true);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6977 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6978 huge_dalloc(x);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6979 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6980 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6981 } else if (reserve_cur > reserve_max) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6982 reserve_shrink();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6983 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6984 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6985 malloc_mutex_unlock(&reserve_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6986
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6987 return (false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6988 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6989
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6990 #ifdef MOZ_MEMORY_WINDOWS
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6991 void*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6992 _recalloc(void *ptr, size_t count, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6993 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6994 size_t oldsize = (ptr != NULL) ? isalloc(ptr) : 0;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6995 size_t newsize = count * size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6996
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6997 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6998 * In order for all trailing bytes to be zeroed, the caller needs to
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
6999 * use calloc(), followed by recalloc(). However, the current calloc()
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7000 * implementation only zeros the bytes requested, so if recalloc() is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7001 * to work 100% correctly, calloc() will need to change to zero
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7002 * trailing bytes.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7003 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7004
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7005 ptr = realloc(ptr, newsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7006 if (ptr != NULL && oldsize < newsize) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7007 memset((void *)((uintptr_t)ptr + oldsize), 0, newsize -
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7008 oldsize);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7009 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7010
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7011 return ptr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7012 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7013
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7014 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7015 * This impl of _expand doesn't ever actually expand or shrink blocks: it
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7016 * simply replies that you may continue using a shrunk block.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7017 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7018 void*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7019 _expand(void *ptr, size_t newsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7020 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7021 if (isalloc(ptr) >= newsize)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7022 return ptr;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7023
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7024 return NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7025 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7026
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7027 size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7028 _msize(const void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7029 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7030
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7031 return malloc_usable_size(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7032 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7033 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7034
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7035 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7036 * End non-standard functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7037 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7038 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7039 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7040 * Begin library-private functions, used by threading libraries for protection
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7041 * of malloc during fork(). These functions are only called if the program is
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7042 * running in threaded mode, so there is no need to check whether the program
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7043 * is threaded here.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7044 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7045
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7046 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7047 _malloc_prefork(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7048 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7049 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7050
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7051 /* Acquire all mutexes in a safe order. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7052
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7053 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7054 for (i = 0; i < narenas; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7055 if (arenas[i] != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7056 malloc_spin_lock(&arenas[i]->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7057 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7058 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7059
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7060 malloc_mutex_lock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7061
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7062 malloc_mutex_lock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7063 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7064
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7065 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7066 _malloc_postfork(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7067 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7068 unsigned i;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7069
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7070 /* Release all mutexes, now that fork() has completed. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7071
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7072 malloc_mutex_unlock(&huge_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7073
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7074 malloc_mutex_unlock(&base_mtx);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7075
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7076 malloc_spin_lock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7077 for (i = 0; i < narenas; i++) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7078 if (arenas[i] != NULL)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7079 malloc_spin_unlock(&arenas[i]->lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7080 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7081 malloc_spin_unlock(&arenas_lock);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7082 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7083
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7084 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7085 * End library-private functions.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7086 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7087 /******************************************************************************/
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7088
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7089 #ifdef HAVE_LIBDL
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7090 # include <dlfcn.h>
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7091 #endif
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7092
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7093 #ifdef MOZ_MEMORY_DARWIN
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7094 static malloc_zone_t zone;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7095 static struct malloc_introspection_t zone_introspect;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7096
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7097 static size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7098 zone_size(malloc_zone_t *zone, void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7099 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7100
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7101 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7102 * There appear to be places within Darwin (such as setenv(3)) that
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7103 * cause calls to this function with pointers that *no* zone owns. If
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7104 * we knew that all pointers were owned by *some* zone, we could split
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7105 * our zone into two parts, and use one as the default allocator and
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7106 * the other as the default deallocator/reallocator. Since that will
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7107 * not work in practice, we must check all pointers to assure that they
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7108 * reside within a mapped chunk before determining size.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7109 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7110 return (isalloc_validate(ptr));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7111 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7112
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7113 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7114 zone_malloc(malloc_zone_t *zone, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7115 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7116
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7117 return (malloc(size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7118 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7119
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7120 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7121 zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7122 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7123
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7124 return (calloc(num, size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7125 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7126
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7127 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7128 zone_valloc(malloc_zone_t *zone, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7129 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7130 void *ret = NULL; /* Assignment avoids useless compiler warning. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7131
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7132 posix_memalign(&ret, pagesize, size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7133
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7134 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7135 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7136
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7137 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7138 zone_free(malloc_zone_t *zone, void *ptr)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7139 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7140
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7141 free(ptr);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7142 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7143
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7144 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7145 zone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7146 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7147
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7148 return (realloc(ptr, size));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7149 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7150
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7151 static void *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7152 zone_destroy(malloc_zone_t *zone)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7153 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7154
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7155 /* This function should never be called. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7156 assert(false);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7157 return (NULL);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7158 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7159
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7160 static size_t
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7161 zone_good_size(malloc_zone_t *zone, size_t size)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7162 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7163 size_t ret;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7164 void *p;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7165
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7166 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7167 * Actually create an object of the appropriate size, then find out
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7168 * how large it could have been without moving up to the next size
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7169 * class.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7170 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7171 p = malloc(size);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7172 if (p != NULL) {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7173 ret = isalloc(p);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7174 free(p);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7175 } else
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7176 ret = size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7177
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7178 return (ret);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7179 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7180
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7181 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7182 zone_force_lock(malloc_zone_t *zone)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7183 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7184
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7185 _malloc_prefork();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7186 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7187
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7188 static void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7189 zone_force_unlock(malloc_zone_t *zone)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7190 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7191
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7192 _malloc_postfork();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7193 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7194
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7195 static malloc_zone_t *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7196 create_zone(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7197 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7198
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7199 assert(malloc_initialized);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7200
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7201 zone.size = (void *)zone_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7202 zone.malloc = (void *)zone_malloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7203 zone.calloc = (void *)zone_calloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7204 zone.valloc = (void *)zone_valloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7205 zone.free = (void *)zone_free;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7206 zone.realloc = (void *)zone_realloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7207 zone.destroy = (void *)zone_destroy;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7208 zone.zone_name = "jemalloc_zone";
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7209 zone.batch_malloc = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7210 zone.batch_free = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7211 zone.introspect = &zone_introspect;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7212
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7213 zone_introspect.enumerator = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7214 zone_introspect.good_size = (void *)zone_good_size;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7215 zone_introspect.check = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7216 zone_introspect.print = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7217 zone_introspect.log = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7218 zone_introspect.force_lock = (void *)zone_force_lock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7219 zone_introspect.force_unlock = (void *)zone_force_unlock;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7220 zone_introspect.statistics = NULL;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7221
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7222 return (&zone);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7223 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7224
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7225 __attribute__((constructor))
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7226 void
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7227 jemalloc_darwin_init(void)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7228 {
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7229 extern unsigned malloc_num_zones;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7230 extern malloc_zone_t **malloc_zones;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7231
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7232 if (malloc_init_hard())
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7233 abort();
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7234
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7235 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7236 * The following code is *not* thread-safe, so it's critical that
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7237 * initialization be manually triggered.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7238 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7239
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7240 /* Register the custom zones. */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7241 malloc_zone_register(create_zone());
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7242 assert(malloc_zones[malloc_num_zones - 1] == &zone);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7243
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7244 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7245 * Shift malloc_zones around so that zone is first, which makes it the
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7246 * default zone.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7247 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7248 assert(malloc_num_zones > 1);
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7249 memmove(&malloc_zones[1], &malloc_zones[0],
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7250 sizeof(malloc_zone_t *) * (malloc_num_zones - 1));
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7251 malloc_zones[0] = &zone;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7252 }
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7253
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7254 #elif defined(__GLIBC__) && !defined(__UCLIBC__)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7255 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7256 * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7257 * to inconsistently reference libc's malloc(3)-compatible functions
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7258 * (bug 493541).
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7259 *
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7260 * These definitions interpose hooks in glibc. The functions are actually
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7261 * passed an extra argument for the caller return address, which will be
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7262 * ignored.
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7263 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7264 void (*__free_hook)(void *ptr) = free;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7265 void *(*__malloc_hook)(size_t size) = malloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7266 void *(*__realloc_hook)(void *ptr, size_t size) = realloc;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7267 void *(*__memalign_hook)(size_t alignment, size_t size) = memalign;
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7268
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7269 #elif defined(RTLD_DEEPBIND)
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7270 /*
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7271 * XXX On systems that support RTLD_GROUP or DF_1_GROUP, do their
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7272 * implementations permit similar inconsistencies? Should STV_SINGLETON
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7273 * visibility be used for interposition where available?
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7274 */
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7275 # error "Interposing malloc is unsafe on this system without libc malloc hooks."
9a44d900ee55 initial import
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
diff changeset
7276 #endif