Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/dlmalloc.c
4150 views
1
2
/* XXX Emscripten XXX */
3
#if __EMSCRIPTEN__
4
// When building for wasm we export `malloc` and `emscripten_builtin_malloc` as
5
// weak alias of the internal `dlmalloc` which is static to this file.
6
#define DLMALLOC_EXPORT static
7
/* mmap uses malloc, so malloc can't use mmap */
8
#define HAVE_MMAP 0
9
/* Emscripten's sbrk can interpret unsigned values greater than (MAX_SIZE_T / 2U) (2GB) correctly */
10
#define UNSIGNED_MORECORE 1
11
/* we can only grow the heap up anyhow, so don't try to trim */
12
#define MORECORE_CANNOT_TRIM 1
13
#ifndef DLMALLOC_DEBUG
14
/* dlmalloc has many checks, calls to abort() increase code size,
15
leave them only in debug builds */
16
#define ABORT __builtin_unreachable()
17
/* allow malloc stats only in debug builds, which brings in stdio code. */
18
#define NO_MALLOC_STATS 1
19
#endif
20
/* XXX Emscripten Tracing API. This defines away the code if tracing is disabled. */
21
#include <emscripten/trace.h>
22
23
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
24
#define USE_LOCKS 1
25
#endif
26
27
/* Make malloc() and free() threadsafe by securing the memory allocations with pthread mutexes. */
28
#if __EMSCRIPTEN_PTHREADS__
29
#define USE_SPIN_LOCKS 0 // Ensure we use pthread_mutex_t.
30
#endif
31
32
#ifndef MALLOC_ALIGNMENT
33
#include <stddef.h>
34
/* `malloc`ed pointers must be aligned at least as strictly as max_align_t. */
35
#define MALLOC_ALIGNMENT (__alignof__(max_align_t))
36
/*
37
Emscripten aligns even float128 to 64-bits, to save size and increase speed.
38
See https://github.com/emscripten-core/emscripten/issues/10072
39
*/
40
_Static_assert(MALLOC_ALIGNMENT == 8, "max_align_t must be 8");
41
#endif
42
43
#endif // __EMSCRIPTEN__
44
45
46
#define __THROW
47
#define __attribute_malloc__
48
#define __wur
49
50
51
/*
52
This is a version (aka dlmalloc) of malloc/free/realloc written by
53
Doug Lea and released to the public domain, as explained at
54
http://creativecommons.org/publicdomain/zero/1.0/ Send questions,
55
comments, complaints, performance data, etc to [email protected]
56
57
* Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea
58
Note: There may be an updated version of this malloc obtainable at
59
ftp://gee.cs.oswego.edu/pub/misc/malloc.c
60
Check before installing!
61
62
* Quickstart
63
64
This library is all in one file to simplify the most common usage:
65
ftp it, compile it (-O3), and link it into another program. All of
66
the compile-time options default to reasonable values for use on
67
most platforms. You might later want to step through various
68
compile-time and dynamic tuning options.
69
70
For convenience, an include file for code using this malloc is at:
71
ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h
72
You don't really need this .h file unless you call functions not
73
defined in your system include files. The .h file contains only the
74
excerpts from this file needed for using this malloc on ANSI C/C++
75
systems, so long as you haven't changed compile-time options about
76
naming and tuning parameters. If you do, then you can create your
77
own malloc.h that does include all settings by cutting at the point
78
indicated below. Note that you may already by default be using a C
79
library containing a malloc that is based on some version of this
80
malloc (for example in linux). You might still want to use the one
81
in this file to customize settings or to avoid overheads associated
82
with library versions.
83
84
* Vital statistics:
85
86
Supported pointer/size_t representation: 4 or 8 bytes
87
size_t MUST be an unsigned type of the same width as
88
pointers. (If you are using an ancient system that declares
89
size_t as a signed type, or need it to be a different width
90
than pointers, you can use a previous release of this malloc
91
(e.g. 2.7.2) supporting these.)
92
93
Alignment: 8 bytes (minimum)
94
This suffices for nearly all current machines and C compilers.
95
However, you can define MALLOC_ALIGNMENT to be wider than this
96
if necessary (up to 128bytes), at the expense of using more space.
97
98
Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes)
99
8 or 16 bytes (if 8byte sizes)
100
Each malloced chunk has a hidden word of overhead holding size
101
and status information, and additional cross-check word
102
if FOOTERS is defined.
103
104
Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead)
105
8-byte ptrs: 32 bytes (including overhead)
106
107
Even a request for zero bytes (i.e., malloc(0)) returns a
108
pointer to something of the minimum allocatable size.
109
The maximum overhead wastage (i.e., number of extra bytes
110
allocated than were requested in malloc) is less than or equal
111
to the minimum size, except for requests >= mmap_threshold that
112
are serviced via mmap(), where the worst case wastage is about
113
32 bytes plus the remainder from a system page (the minimal
114
mmap unit); typically 4096 or 8192 bytes.
115
116
Security: static-safe; optionally more or less
117
The "security" of malloc refers to the ability of malicious
118
code to accentuate the effects of errors (for example, freeing
119
space that is not currently malloc'ed or overwriting past the
120
ends of chunks) in code that calls malloc. This malloc
121
guarantees not to modify any memory locations below the base of
122
heap, i.e., static variables, even in the presence of usage
123
errors. The routines additionally detect most improper frees
124
and reallocs. All this holds as long as the static bookkeeping
125
for malloc itself is not corrupted by some other means. This
126
is only one aspect of security -- these checks do not, and
127
cannot, detect all possible programming errors.
128
129
If FOOTERS is defined nonzero, then each allocated chunk
130
carries an additional check word to verify that it was malloced
131
from its space. These check words are the same within each
132
execution of a program using malloc, but differ across
133
executions, so externally crafted fake chunks cannot be
134
freed. This improves security by rejecting frees/reallocs that
135
could corrupt heap memory, in addition to the checks preventing
136
writes to statics that are always on. This may further improve
137
security at the expense of time and space overhead. (Note that
138
FOOTERS may also be worth using with MSPACES.)
139
140
By default detected errors cause the program to abort (calling
141
"abort()"). You can override this to instead proceed past
142
errors by defining PROCEED_ON_ERROR. In this case, a bad free
143
has no effect, and a malloc that encounters a bad address
144
caused by user overwrites will ignore the bad address by
145
dropping pointers and indices to all known memory. This may
146
be appropriate for programs that should continue if at all
147
possible in the face of programming errors, although they may
148
run out of memory because dropped memory is never reclaimed.
149
150
If you don't like either of these options, you can define
151
CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
152
else. And if if you are sure that your program using malloc has
153
no errors or vulnerabilities, you can define INSECURE to 1,
154
which might (or might not) provide a small performance improvement.
155
156
It is also possible to limit the maximum total allocatable
157
space, using malloc_set_footprint_limit. This is not
158
designed as a security feature in itself (calls to set limits
159
are not screened or privileged), but may be useful as one
160
aspect of a secure implementation.
161
162
Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero
163
When USE_LOCKS is defined, each public call to malloc, free,
164
etc is surrounded with a lock. By default, this uses a plain
165
pthread mutex, win32 critical section, or a spin-lock if if
166
available for the platform and not disabled by setting
167
USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined,
168
recursive versions are used instead (which are not required for
169
base functionality but may be needed in layered extensions).
170
Using a global lock is not especially fast, and can be a major
171
bottleneck. It is designed only to provide minimal protection
172
in concurrent environments, and to provide a basis for
173
extensions. If you are using malloc in a concurrent program,
174
consider instead using nedmalloc
175
(http://www.nedprod.com/programs/portable/nedmalloc/) or
176
ptmalloc (See http://www.malloc.de), which are derived from
177
versions of this malloc.
178
179
System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
180
This malloc can use unix sbrk or any emulation (invoked using
181
the CALL_MORECORE macro) and/or mmap/munmap or any emulation
182
(invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
183
memory. On most unix systems, it tends to work best if both
184
MORECORE and MMAP are enabled. On Win32, it uses emulations
185
based on VirtualAlloc. It also uses common C library functions
186
like memset.
187
188
Compliance: I believe it is compliant with the Single Unix Specification
189
(See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
190
others as well.
191
192
* Overview of algorithms
193
194
This is not the fastest, most space-conserving, most portable, or
195
most tunable malloc ever written. However it is among the fastest
196
while also being among the most space-conserving, portable and
197
tunable. Consistent balance across these factors results in a good
198
general-purpose allocator for malloc-intensive programs.
199
200
In most ways, this malloc is a best-fit allocator. Generally, it
201
chooses the best-fitting existing chunk for a request, with ties
202
broken in approximately least-recently-used order. (This strategy
203
normally maintains low fragmentation.) However, for requests less
204
than 256bytes, it deviates from best-fit when there is not an
205
exactly fitting available chunk by preferring to use space adjacent
206
to that used for the previous small request, as well as by breaking
207
ties in approximately most-recently-used order. (These enhance
208
locality of series of small allocations.) And for very large requests
209
(>= 256Kb by default), it relies on system memory mapping
210
facilities, if supported. (This helps avoid carrying around and
211
possibly fragmenting memory used only for large chunks.)
212
213
All operations (except malloc_stats and mallinfo) have execution
214
times that are bounded by a constant factor of the number of bits in
215
a size_t, not counting any clearing in calloc or copying in realloc,
216
or actions surrounding MORECORE and MMAP that have times
217
proportional to the number of non-contiguous regions returned by
218
system allocation routines, which is often just 1. In real-time
219
applications, you can optionally suppress segment traversals using
220
NO_SEGMENT_TRAVERSAL, which assures bounded execution even when
221
system allocators return non-contiguous spaces, at the typical
222
expense of carrying around more memory and increased fragmentation.
223
224
The implementation is not very modular and seriously overuses
225
macros. Perhaps someday all C compilers will do as good a job
226
inlining modular code as can now be done by brute-force expansion,
227
but now, enough of them seem not to.
228
229
Some compilers issue a lot of warnings about code that is
230
dead/unreachable only on some platforms, and also about intentional
231
uses of negation on unsigned types. All known cases of each can be
232
ignored.
233
234
For a longer but out of date high-level description, see
235
http://gee.cs.oswego.edu/dl/html/malloc.html
236
237
* MSPACES
238
If MSPACES is defined, then in addition to malloc, free, etc.,
239
this file also defines mspace_malloc, mspace_free, etc. These
240
are versions of malloc routines that take an "mspace" argument
241
obtained using create_mspace, to control all internal bookkeeping.
242
If ONLY_MSPACES is defined, only these versions are compiled.
243
So if you would like to use this allocator for only some allocations,
244
and your system malloc for others, you can compile with
245
ONLY_MSPACES and then do something like...
246
static mspace mymspace = create_mspace(0,0); // for example
247
#define mymalloc(bytes) mspace_malloc(mymspace, bytes)
248
249
(Note: If you only need one instance of an mspace, you can instead
250
use "USE_DL_PREFIX" to relabel the global malloc.)
251
252
You can similarly create thread-local allocators by storing
253
mspaces as thread-locals. For example:
254
static __thread mspace tlms = 0;
255
void* tlmalloc(size_t bytes) {
256
if (tlms == 0) tlms = create_mspace(0, 0);
257
return mspace_malloc(tlms, bytes);
258
}
259
void tlfree(void* mem) { mspace_free(tlms, mem); }
260
261
Unless FOOTERS is defined, each mspace is completely independent.
262
You cannot allocate from one and free to another (although
263
conformance is only weakly checked, so usage errors are not always
264
caught). If FOOTERS is defined, then each chunk carries around a tag
265
indicating its originating mspace, and frees are directed to their
266
originating spaces. Normally, this requires use of locks.
267
268
------------------------- Compile-time options ---------------------------
269
270
Be careful in setting #define values for numerical constants of type
271
size_t. On some systems, literal values are not automatically extended
272
to size_t precision unless they are explicitly casted. You can also
273
use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.
274
275
WIN32 default: defined if _WIN32 defined
276
Defining WIN32 sets up defaults for MS environment and compilers.
277
Otherwise defaults are for unix. Beware that there seem to be some
278
cases where this malloc might not be a pure drop-in replacement for
279
Win32 malloc: Random-looking failures from Win32 GDI API's (eg;
280
SetDIBits()) may be due to bugs in some video driver implementations
281
when pixel buffers are malloc()ed, and the region spans more than
282
one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)
283
default granularity, pixel buffers may straddle virtual allocation
284
regions more often than when using the Microsoft allocator. You can
285
avoid this by using VirtualAlloc() and VirtualFree() for all pixel
286
buffers rather than using malloc(). If this is not possible,
287
recompile this malloc with a larger DEFAULT_GRANULARITY. Note:
288
in cases where MSC and gcc (cygwin) are known to differ on WIN32,
289
conditions use _MSC_VER to distinguish them.
290
291
DLMALLOC_EXPORT default: extern
292
Defines how public APIs are declared. If you want to export via a
293
Windows DLL, you might define this as
294
#define DLMALLOC_EXPORT extern __declspec(dllexport)
295
If you want a POSIX ELF shared object, you might use
296
#define DLMALLOC_EXPORT extern __attribute__((visibility("default")))
297
298
MALLOC_ALIGNMENT default: (size_t)(2 * sizeof(void *))
299
Controls the minimum alignment for malloc'ed chunks. It must be a
300
power of two and at least 8, even on machines for which smaller
301
alignments would suffice. It may be defined as larger than this
302
though. Note however that code and data structures are optimized for
303
the case of 8-byte alignment.
304
305
MSPACES default: 0 (false)
306
If true, compile in support for independent allocation spaces.
307
This is only supported if HAVE_MMAP is true.
308
309
ONLY_MSPACES default: 0 (false)
310
If true, only compile in mspace versions, not regular versions.
311
312
USE_LOCKS default: 0 (false)
313
Causes each call to each public routine to be surrounded with
314
pthread or WIN32 mutex lock/unlock. (If set true, this can be
315
overridden on a per-mspace basis for mspace versions.) If set to a
316
non-zero value other than 1, locks are used, but their
317
implementation is left out, so lock functions must be supplied manually,
318
as described below.
319
320
USE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available
321
If true, uses custom spin locks for locking. This is currently
322
supported only gcc >= 4.1, older gccs on x86 platforms, and recent
323
MS compilers. Otherwise, posix locks or win32 critical sections are
324
used.
325
326
USE_RECURSIVE_LOCKS default: not defined
327
If defined nonzero, uses recursive (aka reentrant) locks, otherwise
328
uses plain mutexes. This is not required for malloc proper, but may
329
be needed for layered allocators such as nedmalloc.
330
331
LOCK_AT_FORK default: not defined
332
If defined nonzero, performs pthread_atfork upon initialization
333
to initialize child lock while holding parent lock. The implementation
334
assumes that pthread locks (not custom locks) are being used. In other
335
cases, you may need to customize the implementation.
336
337
FOOTERS default: 0
338
If true, provide extra checking and dispatching by placing
339
information in the footers of allocated chunks. This adds
340
space and time overhead.
341
342
INSECURE default: 0
343
If true, omit checks for usage errors and heap space overwrites.
344
345
USE_DL_PREFIX default: NOT defined
346
Causes compiler to prefix all public routines with the string 'dl'.
347
This can be useful when you only want to use this malloc in one part
348
of a program, using your regular system malloc elsewhere.
349
350
MALLOC_INSPECT_ALL default: NOT defined
351
If defined, compiles malloc_inspect_all and mspace_inspect_all, that
352
perform traversal of all heap space. Unless access to these
353
functions is otherwise restricted, you probably do not want to
354
include them in secure implementations.
355
356
ABORT default: defined as abort()
357
Defines how to abort on failed checks. On most systems, a failed
358
check cannot die with an "assert" or even print an informative
359
message, because the underlying print routines in turn call malloc,
360
which will fail again. Generally, the best policy is to simply call
361
abort(). It's not very useful to do more than this because many
362
errors due to overwriting will show up as address faults (null, odd
363
addresses etc) rather than malloc-triggered checks, so will also
364
abort. Also, most compilers know that abort() does not return, so
365
can better optimize code conditionally calling it.
366
367
PROCEED_ON_ERROR default: defined as 0 (false)
368
Controls whether detected bad addresses cause them to bypassed
369
rather than aborting. If set, detected bad arguments to free and
370
realloc are ignored. And all bookkeeping information is zeroed out
371
upon a detected overwrite of freed heap space, thus losing the
372
ability to ever return it from malloc again, but enabling the
373
application to proceed. If PROCEED_ON_ERROR is defined, the
374
static variable malloc_corruption_error_count is compiled in
375
and can be examined to see if errors have occurred. This option
376
generates slower code than the default abort policy.
377
378
DEBUG default: NOT defined
379
The DEBUG setting is mainly intended for people trying to modify
380
this code or diagnose problems when porting to new platforms.
381
However, it may also be able to better isolate user errors than just
382
using runtime checks. The assertions in the check routines spell
383
out in more detail the assumptions and invariants underlying the
384
algorithms. The checking is fairly extensive, and will slow down
385
execution noticeably. Calling malloc_stats or mallinfo with DEBUG
386
set will attempt to check every non-mmapped allocated and free chunk
387
in the course of computing the summaries.
388
389
ABORT_ON_ASSERT_FAILURE default: defined as 1 (true)
390
Debugging assertion failures can be nearly impossible if your
391
version of the assert macro causes malloc to be called, which will
392
lead to a cascade of further failures, blowing the runtime stack.
393
ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
394
which will usually make debugging easier.
395
396
MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32
397
The action to take before "return 0" when malloc fails to be able to
398
return memory because there is none available.
399
400
HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES
401
True if this system supports sbrk or an emulation of it.
402
403
MORECORE default: sbrk
404
The name of the sbrk-style system routine to call to obtain more
405
memory. See below for guidance on writing custom MORECORE
406
functions. The type of the argument to sbrk/MORECORE varies across
407
systems. It cannot be size_t, because it supports negative
408
arguments, so it is normally the signed type of the same width as
409
size_t (sometimes declared as "intptr_t"). It doesn't much matter
410
though. Internally, we only call it with arguments less than half
411
the max value of a size_t, which should work across all reasonable
412
possibilities, although sometimes generating compiler warnings.
413
414
MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE
415
If true, take advantage of fact that consecutive calls to MORECORE
416
with positive arguments always return contiguous increasing
417
addresses. This is true of unix sbrk. It does not hurt too much to
418
set it true anyway, since malloc copes with non-contiguities.
419
Setting it false when definitely non-contiguous saves time
420
and possibly wasted space it would take to discover this though.
421
422
UNSIGNED_MORECORE default: 0 (false)
423
True if MORECORE can only handle unsigned arguments. This sets
424
MORECORE_CANNOT_TRIM to 1 (true).
425
426
MORECORE_CANNOT_TRIM default: NOT defined
427
True if MORECORE cannot release space back to the system when given
428
negative arguments. This is generally necessary only if you are
429
using a hand-crafted MORECORE function that cannot handle negative
430
arguments.
431
432
NO_SEGMENT_TRAVERSAL default: 0
433
If non-zero, suppresses traversals of memory segments
434
returned by either MORECORE or CALL_MMAP. This disables
435
merging of segments that are contiguous, and selectively
436
releasing them to the OS if unused, but bounds execution times.
437
438
HAVE_MMAP default: 1 (true)
439
True if this system supports mmap or an emulation of it. If so, and
440
HAVE_MORECORE is not true, MMAP is used for all system
441
allocation. If set and HAVE_MORECORE is true as well, MMAP is
442
primarily used to directly allocate very large blocks. It is also
443
used as a backup strategy in cases where MORECORE fails to provide
444
space from system. Note: A single call to MUNMAP is assumed to be
445
able to unmap memory that may have be allocated using multiple calls
446
to MMAP, so long as they are adjacent.
447
448
HAVE_MREMAP default: 1 on linux, else 0
449
If true realloc() uses mremap() to re-allocate large blocks and
450
extend or shrink allocation spaces.
451
452
MMAP_CLEARS default: 1 except on WINCE.
453
True if mmap clears memory so calloc doesn't need to. This is true
454
for standard unix mmap using /dev/zero and on WIN32 except for WINCE.
455
456
USE_BUILTIN_FFS default: 0 (i.e., not used)
457
Causes malloc to use the builtin ffs() function to compute indices.
458
Some compilers may recognize and intrinsify ffs to be faster than the
459
supplied C version. Also, the case of x86 using gcc is special-cased
460
to an asm instruction, so is already as fast as it can be, and so
461
this setting has no effect. Similarly for Win32 under recent MS compilers.
462
(On most x86s, the asm version is only slightly faster than the C version.)
463
464
malloc_getpagesize default: derive from system includes, or 4096.
465
The system page size. To the extent possible, this malloc manages
466
memory from the system in page-size units. This may be (and
467
usually is) a function rather than a constant. This is ignored
468
if WIN32, where page size is determined using getSystemInfo during
469
initialization.
470
471
USE_DEV_RANDOM default: 0 (i.e., not used)
472
Causes malloc to use /dev/random to initialize secure magic seed for
473
stamping footers. Otherwise, the current time is used.
474
475
NO_MALLINFO default: 0
476
If defined, don't compile "mallinfo". This can be a simple way
477
of dealing with mismatches between system declarations and
478
those in this file.
479
480
MALLINFO_FIELD_TYPE default: size_t
481
The type of the fields in the mallinfo struct. This was originally
482
defined as "int" in SVID etc, but is more usefully defined as
483
size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set
484
485
NO_MALLOC_STATS default: 0
486
If defined, don't compile "malloc_stats". This avoids calls to
487
fprintf and bringing in stdio dependencies you might not want.
488
489
REALLOC_ZERO_BYTES_FREES default: not defined
490
This should be set if a call to realloc with zero bytes should
491
be the same as a call to free. Some people think it should. Otherwise,
492
since this malloc returns a unique pointer for malloc(0), so does
493
realloc(p, 0).
494
495
LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
496
LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H
497
LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32
498
Define these if your system does not have these header files.
499
You might need to manually insert some of the declarations they provide.
500
501
DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS,
502
system_info.dwAllocationGranularity in WIN32,
503
otherwise 64K.
504
Also settable using mallopt(M_GRANULARITY, x)
505
The unit for allocating and deallocating memory from the system. On
506
most systems with contiguous MORECORE, there is no reason to
507
make this more than a page. However, systems with MMAP tend to
508
either require or encourage larger granularities. You can increase
509
this value to prevent system allocation functions to be called so
510
often, especially if they are slow. The value must be at least one
511
page and must be a power of two. Setting to 0 causes initialization
512
to either page size or win32 region size. (Note: In previous
513
versions of malloc, the equivalent of this option was called
514
"TOP_PAD")
515
516
DEFAULT_TRIM_THRESHOLD default: 2MB
517
Also settable using mallopt(M_TRIM_THRESHOLD, x)
518
The maximum amount of unused top-most memory to keep before
519
releasing via malloc_trim in free(). Automatic trimming is mainly
520
useful in long-lived programs using contiguous MORECORE. Because
521
trimming via sbrk can be slow on some systems, and can sometimes be
522
wasteful (in cases where programs immediately afterward allocate
523
more large chunks) the value should be high enough so that your
524
overall system performance would improve by releasing this much
525
memory. As a rough guide, you might set to a value close to the
526
average size of a process (program) running on your system.
527
Releasing this much memory would allow such a process to run in
528
memory. Generally, it is worth tuning trim thresholds when a
529
program undergoes phases where several large chunks are allocated
530
and released in ways that can reuse each other's storage, perhaps
531
mixed with phases where there are no such chunks at all. The trim
532
value must be greater than page size to have any useful effect. To
533
disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
534
some people use of mallocing a huge space and then freeing it at
535
program startup, in an attempt to reserve system memory, doesn't
536
have the intended effect under automatic trimming, since that memory
537
will immediately be returned to the system.
538
539
DEFAULT_MMAP_THRESHOLD default: 256K
540
Also settable using mallopt(M_MMAP_THRESHOLD, x)
541
The request size threshold for using MMAP to directly service a
542
request. Requests of at least this size that cannot be allocated
543
using already-existing space will be serviced via mmap. (If enough
544
normal freed space already exists it is used instead.) Using mmap
545
segregates relatively large chunks of memory so that they can be
546
individually obtained and released from the host system. A request
547
serviced through mmap is never reused by any other request (at least
548
not directly; the system may just so happen to remap successive
549
requests to the same locations). Segregating space in this way has
550
the benefits that: Mmapped space can always be individually released
551
back to the system, which helps keep the system level memory demands
552
of a long-lived program low. Also, mapped memory doesn't become
553
`locked' between other chunks, as can happen with normally allocated
554
chunks, which means that even trimming via malloc_trim would not
555
release them. However, it has the disadvantage that the space
556
cannot be reclaimed, consolidated, and then used to service later
557
requests, as happens with normal chunks. The advantages of mmap
558
nearly always outweigh disadvantages for "large" chunks, but the
559
value of "large" may vary across systems. The default is an
560
empirically derived value that works well in most systems. You can
561
disable mmap by setting to MAX_SIZE_T.
562
563
MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
564
The number of consolidated frees between checks to release
565
unused segments when freeing. When using non-contiguous segments,
566
especially with multiple mspaces, checking only for topmost space
567
doesn't always suffice to trigger trimming. To compensate for this,
568
free() will, with a period of MAX_RELEASE_CHECK_RATE (or the
569
current number of segments, if greater) try to release unused
570
segments to the OS when freeing chunks that result in
571
consolidation. The best value for this parameter is a compromise
572
between slowing down frees with relatively costly checks that
573
rarely trigger versus holding on to unused memory. To effectively
574
disable, set to MAX_SIZE_T. This may lead to a very slight speed
575
improvement at the expense of carrying around more memory.
576
*/
577
578
/* Version identifier to allow people to support multiple versions */
579
#ifndef DLMALLOC_VERSION
580
#define DLMALLOC_VERSION 20806
581
#endif /* DLMALLOC_VERSION */
582
583
#ifndef DLMALLOC_EXPORT
584
#define DLMALLOC_EXPORT extern
585
#endif
586
587
#ifndef WIN32
588
#ifdef _WIN32
589
#define WIN32 1
590
#endif /* _WIN32 */
591
#ifdef _WIN32_WCE
592
#define LACKS_FCNTL_H
593
#define WIN32 1
594
#endif /* _WIN32_WCE */
595
#endif /* WIN32 */
596
#ifdef WIN32
597
#define WIN32_LEAN_AND_MEAN
598
#include <windows.h>
599
#include <tchar.h>
600
#define HAVE_MMAP 1
601
#define HAVE_MORECORE 0
602
#define LACKS_UNISTD_H
603
#define LACKS_SYS_PARAM_H
604
#define LACKS_SYS_MMAN_H
605
#define LACKS_STRING_H
606
#define LACKS_STRINGS_H
607
#define LACKS_SYS_TYPES_H
608
#define LACKS_ERRNO_H
609
#define LACKS_SCHED_H
610
#ifndef MALLOC_FAILURE_ACTION
611
#define MALLOC_FAILURE_ACTION
612
#endif /* MALLOC_FAILURE_ACTION */
613
#ifndef MMAP_CLEARS
614
#ifdef _WIN32_WCE /* WINCE reportedly does not clear */
615
#define MMAP_CLEARS 0
616
#else
617
#define MMAP_CLEARS 1
618
#endif /* _WIN32_WCE */
619
#endif /*MMAP_CLEARS */
620
#endif /* WIN32 */
621
622
#if defined(DARWIN) || defined(_DARWIN)
623
/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
624
#ifndef HAVE_MORECORE
625
#define HAVE_MORECORE 0
626
#define HAVE_MMAP 1
627
/* OSX allocators provide 16 byte alignment */
628
#ifndef MALLOC_ALIGNMENT
629
#define MALLOC_ALIGNMENT ((size_t)16U)
630
#endif
631
#endif /* HAVE_MORECORE */
632
#endif /* DARWIN */
633
634
#ifndef LACKS_SYS_TYPES_H
635
#include <sys/types.h> /* For size_t */
636
#endif /* LACKS_SYS_TYPES_H */
637
638
/* The maximum possible size_t value has all bits set */
639
#define MAX_SIZE_T (~(size_t)0)
640
641
#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */
642
/* XXX: The following block adapted locally to avoid
643
clean up new Clang -Wexpansion-to-defined warnings.
644
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160118/147239.html */
645
#if (defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
646
(defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)
647
#define USE_LOCKS 1
648
#else
649
#define USE_LOCKS 0
650
#endif
651
#endif /* USE_LOCKS */
652
653
#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */
654
#if ((defined(__GNUC__) && \
655
((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \
656
defined(__i386__) || defined(__x86_64__))) || \
657
(defined(_MSC_VER) && _MSC_VER>=1310))
658
#ifndef USE_SPIN_LOCKS
659
#define USE_SPIN_LOCKS 1
660
#endif /* USE_SPIN_LOCKS */
661
#elif USE_SPIN_LOCKS
662
#error "USE_SPIN_LOCKS defined without implementation"
663
#endif /* ... locks available... */
664
#elif !defined(USE_SPIN_LOCKS)
665
#define USE_SPIN_LOCKS 0
666
#endif /* USE_LOCKS */
667
668
#ifndef ONLY_MSPACES
669
#define ONLY_MSPACES 0
670
#endif /* ONLY_MSPACES */
671
#ifndef MSPACES
672
#if ONLY_MSPACES
673
#define MSPACES 1
674
#else /* ONLY_MSPACES */
675
#define MSPACES 0
676
#endif /* ONLY_MSPACES */
677
#endif /* MSPACES */
678
#ifndef MALLOC_ALIGNMENT
679
#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
680
#endif /* MALLOC_ALIGNMENT */
681
#ifndef FOOTERS
682
#define FOOTERS 0
683
#endif /* FOOTERS */
684
#ifndef ABORT
685
#define ABORT abort()
686
#endif /* ABORT */
687
#ifndef ABORT_ON_ASSERT_FAILURE
688
#define ABORT_ON_ASSERT_FAILURE 1
689
#endif /* ABORT_ON_ASSERT_FAILURE */
690
#ifndef PROCEED_ON_ERROR
691
#define PROCEED_ON_ERROR 0
692
#endif /* PROCEED_ON_ERROR */
693
694
#ifndef INSECURE
695
#define INSECURE 0
696
#endif /* INSECURE */
697
#ifndef MALLOC_INSPECT_ALL
698
#define MALLOC_INSPECT_ALL 0
699
#endif /* MALLOC_INSPECT_ALL */
700
#ifndef HAVE_MMAP
701
#define HAVE_MMAP 1
702
#endif /* HAVE_MMAP */
703
#ifndef MMAP_CLEARS
704
#define MMAP_CLEARS 1
705
#endif /* MMAP_CLEARS */
706
#ifndef HAVE_MREMAP
707
#ifdef linux
708
#define HAVE_MREMAP 1
709
#define _GNU_SOURCE /* Turns on mremap() definition */
710
#else /* linux */
711
#define HAVE_MREMAP 0
712
#endif /* linux */
713
#endif /* HAVE_MREMAP */
714
#ifndef MALLOC_FAILURE_ACTION
715
#define MALLOC_FAILURE_ACTION errno = ENOMEM;
716
#endif /* MALLOC_FAILURE_ACTION */
717
#ifndef HAVE_MORECORE
718
#if ONLY_MSPACES
719
#define HAVE_MORECORE 0
720
#else /* ONLY_MSPACES */
721
#define HAVE_MORECORE 1
722
#endif /* ONLY_MSPACES */
723
#endif /* HAVE_MORECORE */
724
#ifndef UNSIGNED_MORECORE
725
#define UNSIGNED_MORECORE 0
726
#endif /* UNSIGNED_MORECORE */
727
#if UNSIGNED_MORECORE
728
#define MORECORE_CANNOT_TRIM 1
729
#endif /* UNSIGNED_MORECORE */
730
#if !HAVE_MORECORE
731
#define MORECORE_CONTIGUOUS 0
732
#else /* !HAVE_MORECORE */
733
#define MORECORE_DEFAULT sbrk
734
#ifndef MORECORE_CONTIGUOUS
735
#define MORECORE_CONTIGUOUS 1
736
#endif /* MORECORE_CONTIGUOUS */
737
#endif /* HAVE_MORECORE */
738
#ifndef DEFAULT_GRANULARITY
739
#if (MORECORE_CONTIGUOUS || defined(WIN32))
740
#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */
741
#else /* MORECORE_CONTIGUOUS */
742
#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
743
#endif /* MORECORE_CONTIGUOUS */
744
#endif /* DEFAULT_GRANULARITY */
745
#ifndef DEFAULT_TRIM_THRESHOLD
746
#ifndef MORECORE_CANNOT_TRIM
747
#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
748
#else /* MORECORE_CANNOT_TRIM */
749
#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
750
#endif /* MORECORE_CANNOT_TRIM */
751
#endif /* DEFAULT_TRIM_THRESHOLD */
752
#ifndef DEFAULT_MMAP_THRESHOLD
753
#if HAVE_MMAP
754
#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
755
#else /* HAVE_MMAP */
756
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
757
#endif /* HAVE_MMAP */
758
#endif /* DEFAULT_MMAP_THRESHOLD */
759
#ifndef MAX_RELEASE_CHECK_RATE
760
#if HAVE_MMAP
761
#define MAX_RELEASE_CHECK_RATE 4095
762
#else
763
#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T
764
#endif /* HAVE_MMAP */
765
#endif /* MAX_RELEASE_CHECK_RATE */
766
#ifndef USE_BUILTIN_FFS
767
#define USE_BUILTIN_FFS 0
768
#endif /* USE_BUILTIN_FFS */
769
#ifndef USE_DEV_RANDOM
770
#define USE_DEV_RANDOM 0
771
#endif /* USE_DEV_RANDOM */
772
#ifndef NO_MALLINFO
773
#define NO_MALLINFO 0
774
#endif /* NO_MALLINFO */
775
#ifndef MALLINFO_FIELD_TYPE
776
#define MALLINFO_FIELD_TYPE size_t
777
#endif /* MALLINFO_FIELD_TYPE */
778
#ifndef NO_MALLOC_STATS
779
#define NO_MALLOC_STATS 0
780
#endif /* NO_MALLOC_STATS */
781
#ifndef NO_SEGMENT_TRAVERSAL
782
#define NO_SEGMENT_TRAVERSAL 0
783
#endif /* NO_SEGMENT_TRAVERSAL */
784
785
/*
786
mallopt tuning options. SVID/XPG defines four standard parameter
787
numbers for mallopt, normally defined in malloc.h. None of these
788
are used in this malloc, so setting them has no effect. But this
789
malloc does support the following options.
790
*/
791
792
#define M_TRIM_THRESHOLD (-1)
793
#define M_GRANULARITY (-2)
794
#define M_MMAP_THRESHOLD (-3)
795
796
/* ------------------------ Mallinfo declarations ------------------------ */
797
798
#if !NO_MALLINFO
799
/*
800
This version of malloc supports the standard SVID/XPG mallinfo
801
routine that returns a struct containing usage properties and
802
statistics. It should work on any system that has a
803
/usr/include/malloc.h defining struct mallinfo. The main
804
declaration needed is the mallinfo struct that is returned (by-copy)
805
by mallinfo(). The malloinfo struct contains a bunch of fields that
806
are not even meaningful in this version of malloc. These fields are
807
are instead filled by mallinfo() with other numbers that might be of
808
interest.
809
810
HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
811
/usr/include/malloc.h file that includes a declaration of struct
812
mallinfo. If so, it is included; else a compliant version is
813
declared below. These must be precisely the same for mallinfo() to
814
work. The original SVID version of this struct, defined on most
815
systems with mallinfo, declares all fields as ints. But some others
816
define as unsigned long. If your system defines the fields using a
817
type of different width than listed here, you MUST #include your
818
system version and #define HAVE_USR_INCLUDE_MALLOC_H.
819
*/
820
821
/* #define HAVE_USR_INCLUDE_MALLOC_H */
822
823
#ifdef HAVE_USR_INCLUDE_MALLOC_H
824
#include "/usr/include/malloc.h"
825
#else /* HAVE_USR_INCLUDE_MALLOC_H */
826
#ifndef STRUCT_MALLINFO_DECLARED
827
/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */
828
#define _STRUCT_MALLINFO
829
#define STRUCT_MALLINFO_DECLARED 1
830
struct mallinfo {
831
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
832
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
833
MALLINFO_FIELD_TYPE smblks; /* always 0 */
834
MALLINFO_FIELD_TYPE hblks; /* always 0 */
835
MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */
836
MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */
837
MALLINFO_FIELD_TYPE fsmblks; /* always 0 */
838
MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
839
MALLINFO_FIELD_TYPE fordblks; /* total free space */
840
MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
841
};
842
#endif /* STRUCT_MALLINFO_DECLARED */
843
#endif /* HAVE_USR_INCLUDE_MALLOC_H */
844
#endif /* NO_MALLINFO */
845
846
/*
847
Try to persuade compilers to inline. The most critical functions for
848
inlining are defined as macros, so these aren't used for them.
849
*/
850
851
#ifndef FORCEINLINE
852
#if defined(__GNUC__)
853
#define FORCEINLINE __inline __attribute__ ((always_inline))
854
#elif defined(_MSC_VER)
855
#define FORCEINLINE __forceinline
856
#endif
857
#endif
858
#ifndef NOINLINE
859
#if defined(__GNUC__)
860
#define NOINLINE __attribute__ ((noinline))
861
#elif defined(_MSC_VER)
862
#define NOINLINE __declspec(noinline)
863
#else
864
#define NOINLINE
865
#endif
866
#endif
867
868
#ifdef __cplusplus
869
extern "C" {
870
#ifndef FORCEINLINE
871
#define FORCEINLINE inline
872
#endif
873
#endif /* __cplusplus */
874
#ifndef FORCEINLINE
875
#define FORCEINLINE
876
#endif
877
878
#if !ONLY_MSPACES
879
880
/* ------------------- Declarations of public routines ------------------- */
881
882
#ifndef USE_DL_PREFIX
883
// XXX Emscripten XXX
884
#if defined(__EMSCRIPTEN__)
885
void* __libc_malloc(size_t) __attribute__((weak, alias("dlmalloc")));
886
void __libc_free(void*) __attribute__((weak, alias("dlfree")));
887
void* __libc_calloc(size_t) __attribute__((weak, alias("dlcalloc")));
888
void* __libc_realloc(void*, size_t) __attribute__((weak, alias("dlrealloc")));
889
void* malloc(size_t) __attribute__((weak, alias("dlmalloc")));
890
void free(void*) __attribute__((weak, alias("dlfree")));
891
void* calloc(size_t, size_t) __attribute__((weak, alias("dlcalloc")));
892
void* realloc(void*, size_t) __attribute__((weak, alias("dlrealloc")));
893
void* realloc_in_place(void*, size_t) __attribute__((weak, alias("dlrealloc_in_place")));
894
void* memalign(size_t, size_t) __attribute__((weak, alias("dlmemalign")));
895
int posix_memalign(void**, size_t, size_t) __attribute__((weak, alias("dlposix_memalign")));
896
void* valloc(size_t) __attribute__((weak, alias("dlvalloc")));
897
void* pvalloc(size_t) __attribute__((weak, alias("dlpvalloc")));
898
#if !NO_MALLINFO
899
struct mallinfo mallinfo(void) __attribute__((weak, alias("dlmallinfo")));
900
#endif
901
int mallopt(int, int) __attribute__((weak, alias("dlmallopt")));
902
int malloc_trim(size_t) __attribute__((weak, alias("dlmalloc_trim")));
903
#if !NO_MALLOC_STATS
904
void malloc_stats(void) __attribute__((weak, alias("dlmalloc_stats")));
905
#endif
906
size_t malloc_usable_size(const void*) __attribute__((weak, alias("dlmalloc_usable_size")));
907
size_t malloc_footprint(void) __attribute__((weak, alias("dlmalloc_footprint")));
908
size_t malloc_max_footprint(void) __attribute__((weak, alias("dlmalloc_max_footprint")));
909
size_t malloc_footprint_limit(void) __attribute__((weak, alias("dlmalloc_footprint_limit")));
910
size_t malloc_set_footprint_limit(size_t bytes) __attribute__((weak, alias("dlmalloc_set_footprint_limit")));
911
#if MALLOC_INSPECT_ALL
912
void malloc_inspect_all(void(*handler)(void*, void *, size_t, void*), void* arg) __attribute__((weak, alias("dlmalloc_inspect_all")));
913
#endif
914
void** independent_calloc(size_t, size_t, void**) __attribute__((weak, alias("dlindependent_calloc")));
915
void** independent_comalloc(size_t, size_t*, void**) __attribute__((weak, alias("dlindependent_comalloc")));
916
size_t bulk_free(void**, size_t n_elements) __attribute__((weak, alias("dlbulk_free")));
917
#endif /*__EMSCRIPTEN__*/
918
#endif /* USE_DL_PREFIX */
919
920
/*
921
malloc(size_t n)
922
Returns a pointer to a newly allocated chunk of at least n bytes, or
923
null if no space is available, in which case errno is set to ENOMEM
924
on ANSI C systems.
925
926
If n is zero, malloc returns a minimum-sized chunk. (The minimum
927
size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
928
systems.) Note that size_t is an unsigned type, so calls with
929
arguments that would be negative if signed are interpreted as
930
requests for huge amounts of space, which will often fail. The
931
maximum supported value of n differs across systems, but is in all
932
cases less than the maximum representable value of a size_t.
933
*/
934
DLMALLOC_EXPORT void* dlmalloc(size_t);
935
936
/*
937
free(void* p)
938
Releases the chunk of memory pointed to by p, that had been previously
939
allocated using malloc or a related routine such as realloc.
940
It has no effect if p is null. If p was not malloced or already
941
freed, free(p) will by default cause the current program to abort.
942
*/
943
DLMALLOC_EXPORT void dlfree(void*);
944
945
/*
946
calloc(size_t n_elements, size_t element_size);
947
Returns a pointer to n_elements * element_size bytes, with all locations
948
set to zero.
949
*/
950
DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);
951
952
/*
953
realloc(void* p, size_t n)
954
Returns a pointer to a chunk of size n that contains the same data
955
as does chunk p up to the minimum of (n, p's size) bytes, or null
956
if no space is available.
957
958
The returned pointer may or may not be the same as p. The algorithm
959
prefers extending p in most cases when possible, otherwise it
960
employs the equivalent of a malloc-copy-free sequence.
961
962
If p is null, realloc is equivalent to malloc.
963
964
If space is not available, realloc returns null, errno is set (if on
965
ANSI) and p is NOT freed.
966
967
if n is for fewer bytes than already held by p, the newly unused
968
space is lopped off and freed if possible. realloc with a size
969
argument of zero (re)allocates a minimum-sized chunk.
970
971
The old unix realloc convention of allowing the last-free'd chunk
972
to be used as an argument to realloc is not supported.
973
*/
974
DLMALLOC_EXPORT void* dlrealloc(void*, size_t);
975
976
/*
977
realloc_in_place(void* p, size_t n)
978
Resizes the space allocated for p to size n, only if this can be
979
done without moving p (i.e., only if there is adjacent space
980
available if n is greater than p's current allocated size, or n is
981
less than or equal to p's size). This may be used instead of plain
982
realloc if an alternative allocation strategy is needed upon failure
983
to expand space; for example, reallocation of a buffer that must be
984
memory-aligned or cleared. You can use realloc_in_place to trigger
985
these alternatives only when needed.
986
987
Returns p if successful; otherwise null.
988
*/
989
DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t);
990
991
/*
992
memalign(size_t alignment, size_t n);
993
Returns a pointer to a newly allocated chunk of n bytes, aligned
994
in accord with the alignment argument.
995
996
The alignment argument should be a power of two. If the argument is
997
not a power of two, the nearest greater power is used.
998
8-byte alignment is guaranteed by normal malloc calls, so don't
999
bother calling memalign with an argument of 8 or less.
1000
1001
Overreliance on memalign is a sure way to fragment space.
1002
*/
1003
DLMALLOC_EXPORT void* dlmemalign(size_t, size_t);
1004
1005
/*
1006
int posix_memalign(void** pp, size_t alignment, size_t n);
1007
Allocates a chunk of n bytes, aligned in accord with the alignment
1008
argument. Differs from memalign only in that it (1) assigns the
1009
allocated memory to *pp rather than returning it, (2) fails and
1010
returns EINVAL if the alignment is not a power of two (3) fails and
1011
returns ENOMEM if memory cannot be allocated.
1012
*/
1013
DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t);
1014
1015
/*
1016
valloc(size_t n);
1017
Equivalent to memalign(pagesize, n), where pagesize is the page
1018
size of the system. If the pagesize is unknown, 4096 is used.
1019
*/
1020
DLMALLOC_EXPORT void* dlvalloc(size_t);
1021
1022
/*
1023
mallopt(int parameter_number, int parameter_value)
1024
Sets tunable parameters The format is to provide a
1025
(parameter-number, parameter-value) pair. mallopt then sets the
1026
corresponding parameter to the argument value if it can (i.e., so
1027
long as the value is meaningful), and returns 1 if successful else
1028
0. To workaround the fact that mallopt is specified to use int,
1029
not size_t parameters, the value -1 is specially treated as the
1030
maximum unsigned size_t value.
1031
1032
SVID/XPG/ANSI defines four standard param numbers for mallopt,
1033
normally defined in malloc.h. None of these are use in this malloc,
1034
so setting them has no effect. But this malloc also supports other
1035
options in mallopt. See below for details. Briefly, supported
1036
parameters are as follows (listed defaults are for "typical"
1037
configurations).
1038
1039
Symbol param # default allowed param values
1040
M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables)
1041
M_GRANULARITY -2 page size any power of 2 >= page size
1042
M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support)
1043
*/
1044
DLMALLOC_EXPORT int dlmallopt(int, int);
1045
1046
/*
1047
malloc_footprint();
1048
Returns the number of bytes obtained from the system. The total
1049
number of bytes allocated by malloc, realloc etc., is less than this
1050
value. Unlike mallinfo, this function returns only a precomputed
1051
result, so can be called frequently to monitor memory consumption.
1052
Even if locks are otherwise defined, this function does not use them,
1053
so results might not be up to date.
1054
*/
1055
DLMALLOC_EXPORT size_t dlmalloc_footprint(void);
1056
1057
/*
1058
malloc_max_footprint();
1059
Returns the maximum number of bytes obtained from the system. This
1060
value will be greater than current footprint if deallocated space
1061
has been reclaimed by the system. The peak number of bytes allocated
1062
by malloc, realloc etc., is less than this value. Unlike mallinfo,
1063
this function returns only a precomputed result, so can be called
1064
frequently to monitor memory consumption. Even if locks are
1065
otherwise defined, this function does not use them, so results might
1066
not be up to date.
1067
*/
1068
DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void);
1069
1070
/*
1071
malloc_footprint_limit();
1072
Returns the number of bytes that the heap is allowed to obtain from
1073
the system, returning the last value returned by
1074
malloc_set_footprint_limit, or the maximum size_t value if
1075
never set. The returned value reflects a permission. There is no
1076
guarantee that this number of bytes can actually be obtained from
1077
the system.
1078
*/
1079
DLMALLOC_EXPORT size_t dlmalloc_footprint_limit();
1080
1081
/*
1082
malloc_set_footprint_limit();
1083
Sets the maximum number of bytes to obtain from the system, causing
1084
failure returns from malloc and related functions upon attempts to
1085
exceed this value. The argument value may be subject to page
1086
rounding to an enforceable limit; this actual value is returned.
1087
Using an argument of the maximum possible size_t effectively
1088
disables checks. If the argument is less than or equal to the
1089
current malloc_footprint, then all future allocations that require
1090
additional system memory will fail. However, invocation cannot
1091
retroactively deallocate existing used memory.
1092
*/
1093
DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes);
1094
1095
#if MALLOC_INSPECT_ALL
1096
/*
1097
malloc_inspect_all(void(*handler)(void *start,
1098
void *end,
1099
size_t used_bytes,
1100
void* callback_arg),
1101
void* arg);
1102
Traverses the heap and calls the given handler for each managed
1103
region, skipping all bytes that are (or may be) used for bookkeeping
1104
purposes. Traversal does not include include chunks that have been
1105
directly memory mapped. Each reported region begins at the start
1106
address, and continues up to but not including the end address. The
1107
first used_bytes of the region contain allocated data. If
1108
used_bytes is zero, the region is unallocated. The handler is
1109
invoked with the given callback argument. If locks are defined, they
1110
are held during the entire traversal. It is a bad idea to invoke
1111
other malloc functions from within the handler.
1112
1113
For example, to count the number of in-use chunks with size greater
1114
than 1000, you could write:
1115
static int count = 0;
1116
void count_chunks(void* start, void* end, size_t used, void* arg) {
1117
if (used >= 1000) ++count;
1118
}
1119
then:
1120
malloc_inspect_all(count_chunks, NULL);
1121
1122
malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
1123
*/
1124
DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
1125
void* arg);
1126
1127
#endif /* MALLOC_INSPECT_ALL */
1128
1129
#if !NO_MALLINFO
1130
/*
1131
mallinfo()
1132
Returns (by copy) a struct containing various summary statistics:
1133
1134
arena: current total non-mmapped bytes allocated from system
1135
ordblks: the number of free chunks
1136
smblks: always zero.
1137
hblks: current number of mmapped regions
1138
hblkhd: total bytes held in mmapped regions
1139
usmblks: the maximum total allocated space. This will be greater
1140
than current total if trimming has occurred.
1141
fsmblks: always zero
1142
uordblks: current total allocated space (normal or mmapped)
1143
fordblks: total free space
1144
keepcost: the maximum number of bytes that could ideally be released
1145
back to system via malloc_trim. ("ideally" means that
1146
it ignores page restrictions etc.)
1147
1148
Because these fields are ints, but internal bookkeeping may
1149
be kept as longs, the reported values may wrap around zero and
1150
thus be inaccurate.
1151
*/
1152
DLMALLOC_EXPORT struct mallinfo dlmallinfo(void);
1153
#endif /* NO_MALLINFO */
1154
1155
/*
1156
independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
1157
1158
independent_calloc is similar to calloc, but instead of returning a
1159
single cleared space, it returns an array of pointers to n_elements
1160
independent elements that can hold contents of size elem_size, each
1161
of which starts out cleared, and can be independently freed,
1162
realloc'ed etc. The elements are guaranteed to be adjacently
1163
allocated (this is not guaranteed to occur with multiple callocs or
1164
mallocs), which may also improve cache locality in some
1165
applications.
1166
1167
The "chunks" argument is optional (i.e., may be null, which is
1168
probably the most typical usage). If it is null, the returned array
1169
is itself dynamically allocated and should also be freed when it is
1170
no longer needed. Otherwise, the chunks array must be of at least
1171
n_elements in length. It is filled in with the pointers to the
1172
chunks.
1173
1174
In either case, independent_calloc returns this pointer array, or
1175
null if the allocation failed. If n_elements is zero and "chunks"
1176
is null, it returns a chunk representing an array with zero elements
1177
(which should be freed if not wanted).
1178
1179
Each element must be freed when it is no longer needed. This can be
1180
done all at once using bulk_free.
1181
1182
independent_calloc simplifies and speeds up implementations of many
1183
kinds of pools. It may also be useful when constructing large data
1184
structures that initially have a fixed number of fixed-sized nodes,
1185
but the number is not known at compile time, and some of the nodes
1186
may later need to be freed. For example:
1187
1188
struct Node { int item; struct Node* next; };
1189
1190
struct Node* build_list() {
1191
struct Node** pool;
1192
int n = read_number_of_nodes_needed();
1193
if (n <= 0) return 0;
1194
pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
1195
if (pool == 0) die();
1196
// organize into a linked list...
1197
struct Node* first = pool[0];
1198
for (i = 0; i < n-1; ++i)
1199
pool[i]->next = pool[i+1];
1200
free(pool); // Can now free the array (or not, if it is needed later)
1201
return first;
1202
}
1203
*/
1204
DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**);
1205
1206
/*
1207
independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
1208
1209
independent_comalloc allocates, all at once, a set of n_elements
1210
chunks with sizes indicated in the "sizes" array. It returns
1211
an array of pointers to these elements, each of which can be
1212
independently freed, realloc'ed etc. The elements are guaranteed to
1213
be adjacently allocated (this is not guaranteed to occur with
1214
multiple callocs or mallocs), which may also improve cache locality
1215
in some applications.
1216
1217
The "chunks" argument is optional (i.e., may be null). If it is null
1218
the returned array is itself dynamically allocated and should also
1219
be freed when it is no longer needed. Otherwise, the chunks array
1220
must be of at least n_elements in length. It is filled in with the
1221
pointers to the chunks.
1222
1223
In either case, independent_comalloc returns this pointer array, or
1224
null if the allocation failed. If n_elements is zero and chunks is
1225
null, it returns a chunk representing an array with zero elements
1226
(which should be freed if not wanted).
1227
1228
Each element must be freed when it is no longer needed. This can be
1229
done all at once using bulk_free.
1230
1231
independent_comallac differs from independent_calloc in that each
1232
element may have a different size, and also that it does not
1233
automatically clear elements.
1234
1235
independent_comalloc can be used to speed up allocation in cases
1236
where several structs or objects must always be allocated at the
1237
same time. For example:
1238
1239
struct Head { ... }
1240
struct Foot { ... }
1241
1242
void send_message(char* msg) {
1243
int msglen = strlen(msg);
1244
size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
1245
void* chunks[3];
1246
if (independent_comalloc(3, sizes, chunks) == 0)
1247
die();
1248
struct Head* head = (struct Head*)(chunks[0]);
1249
char* body = (char*)(chunks[1]);
1250
struct Foot* foot = (struct Foot*)(chunks[2]);
1251
// ...
1252
}
1253
1254
In general though, independent_comalloc is worth using only for
1255
larger values of n_elements. For small values, you probably won't
1256
detect enough difference from series of malloc calls to bother.
1257
1258
Overuse of independent_comalloc can increase overall memory usage,
1259
since it cannot reuse existing noncontiguous small chunks that
1260
might be available for some of the elements.
1261
*/
1262
DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**);
1263
1264
/*
1265
bulk_free(void* array[], size_t n_elements)
1266
Frees and clears (sets to null) each non-null pointer in the given
1267
array. This is likely to be faster than freeing them one-by-one.
1268
If footers are used, pointers that have been allocated in different
1269
mspaces are not freed or cleared, and the count of all such pointers
1270
is returned. For large arrays of pointers with poor locality, it
1271
may be worthwhile to sort this array before calling bulk_free.
1272
*/
1273
DLMALLOC_EXPORT size_t dlbulk_free(void**, size_t n_elements);
1274
1275
/*
1276
pvalloc(size_t n);
1277
Equivalent to valloc(minimum-page-that-holds(n)), that is,
1278
round up n to nearest pagesize.
1279
*/
1280
DLMALLOC_EXPORT void* dlpvalloc(size_t);
1281
1282
/*
1283
malloc_trim(size_t pad);
1284
1285
If possible, gives memory back to the system (via negative arguments
1286
to sbrk) if there is unused memory at the `high' end of the malloc
1287
pool or in unused MMAP segments. You can call this after freeing
1288
large blocks of memory to potentially reduce the system-level memory
1289
requirements of a program. However, it cannot guarantee to reduce
1290
memory. Under some allocation patterns, some large free blocks of
1291
memory will be locked between two used chunks, so they cannot be
1292
given back to the system.
1293
1294
The `pad' argument to malloc_trim represents the amount of free
1295
trailing space to leave untrimmed. If this argument is zero, only
1296
the minimum amount of memory to maintain internal data structures
1297
will be left. Non-zero arguments can be supplied to maintain enough
1298
trailing space to service future expected allocations without having
1299
to re-obtain memory from the system.
1300
1301
Malloc_trim returns 1 if it actually released any memory, else 0.
1302
*/
1303
DLMALLOC_EXPORT int dlmalloc_trim(size_t);
1304
1305
/*
1306
malloc_stats();
1307
Prints on stderr the amount of space obtained from the system (both
1308
via sbrk and mmap), the maximum amount (which may be more than
1309
current if malloc_trim and/or munmap got called), and the current
1310
number of bytes allocated via malloc (or realloc, etc) but not yet
1311
freed. Note that this is the number of bytes allocated, not the
1312
number requested. It will be larger than the number requested
1313
because of alignment and bookkeeping overhead. Because it includes
1314
alignment wastage as being in use, this figure may be greater than
1315
zero even when no user-level chunks are allocated.
1316
1317
The reported current and maximum system memory can be inaccurate if
1318
a program makes other calls to system memory allocation functions
1319
(normally sbrk) outside of malloc.
1320
1321
malloc_stats prints only the most commonly interesting statistics.
1322
More information can be obtained by calling mallinfo.
1323
*/
1324
DLMALLOC_EXPORT void dlmalloc_stats(void);
1325
1326
/*
1327
malloc_usable_size(void* p);
1328
1329
Returns the number of bytes you can actually use in
1330
an allocated chunk, which may be more than you requested (although
1331
often not) due to alignment and minimum size constraints.
1332
You can use this many bytes without worrying about
1333
overwriting other allocated objects. This is not a particularly great
1334
programming practice. malloc_usable_size can be more useful in
1335
debugging and assertions, for example:
1336
1337
p = malloc(n);
1338
assert(malloc_usable_size(p) >= 256);
1339
*/
1340
/* XXX EMSCRIPTEN: mark for export (and therefore weak) */
1341
DLMALLOC_EXPORT size_t dlmalloc_usable_size(void*);
1342
1343
#endif /* ONLY_MSPACES */
1344
1345
#if MSPACES
1346
1347
/*
1348
mspace is an opaque type representing an independent
1349
region of space that supports mspace_malloc, etc.
1350
*/
1351
typedef void* mspace;
1352
1353
/*
1354
create_mspace creates and returns a new independent space with the
1355
given initial capacity, or, if 0, the default granularity size. It
1356
returns null if there is no system memory available to create the
1357
space. If argument locked is non-zero, the space uses a separate
1358
lock to control access. The capacity of the space will grow
1359
dynamically as needed to service mspace_malloc requests. You can
1360
control the sizes of incremental increases of this space by
1361
compiling with a different DEFAULT_GRANULARITY or dynamically
1362
setting with mallopt(M_GRANULARITY, value).
1363
*/
1364
DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked);
1365
1366
/*
1367
destroy_mspace destroys the given space, and attempts to return all
1368
of its memory back to the system, returning the total number of
1369
bytes freed. After destruction, the results of access to all memory
1370
used by the space become undefined.
1371
*/
1372
DLMALLOC_EXPORT size_t destroy_mspace(mspace msp);
1373
1374
/*
1375
create_mspace_with_base uses the memory supplied as the initial base
1376
of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
1377
space is used for bookkeeping, so the capacity must be at least this
1378
large. (Otherwise 0 is returned.) When this initial space is
1379
exhausted, additional memory will be obtained from the system.
1380
Destroying this space will deallocate all additionally allocated
1381
space (if possible) but not the initial base.
1382
*/
1383
DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked);
1384
1385
/*
1386
mspace_track_large_chunks controls whether requests for large chunks
1387
are allocated in their own untracked mmapped regions, separate from
1388
others in this mspace. By default large chunks are not tracked,
1389
which reduces fragmentation. However, such chunks are not
1390
necessarily released to the system upon destroy_mspace. Enabling
1391
tracking by setting to true may increase fragmentation, but avoids
1392
leakage when relying on destroy_mspace to release all memory
1393
allocated using this space. The function returns the previous
1394
setting.
1395
*/
1396
DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable);
1397
1398
1399
/*
1400
mspace_malloc behaves as malloc, but operates within
1401
the given space.
1402
*/
1403
DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes);
1404
1405
/*
1406
mspace_free behaves as free, but operates within
1407
the given space.
1408
1409
If compiled with FOOTERS==1, mspace_free is not actually needed.
1410
free may be called instead of mspace_free because freed chunks from
1411
any space are handled by their originating spaces.
1412
*/
1413
DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem);
1414
1415
/*
1416
mspace_realloc behaves as realloc, but operates within
1417
the given space.
1418
1419
If compiled with FOOTERS==1, mspace_realloc is not actually
1420
needed. realloc may be called instead of mspace_realloc because
1421
realloced chunks from any space are handled by their originating
1422
spaces.
1423
*/
1424
DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize);
1425
1426
/*
1427
mspace_calloc behaves as calloc, but operates within
1428
the given space.
1429
*/
1430
DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
1431
1432
/*
1433
mspace_memalign behaves as memalign, but operates within
1434
the given space.
1435
*/
1436
DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
1437
1438
/*
1439
mspace_independent_calloc behaves as independent_calloc, but
1440
operates within the given space.
1441
*/
1442
DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements,
1443
size_t elem_size, void* chunks[]);
1444
1445
/*
1446
mspace_independent_comalloc behaves as independent_comalloc, but
1447
operates within the given space.
1448
*/
1449
DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements,
1450
size_t sizes[], void* chunks[]);
1451
1452
/*
1453
mspace_footprint() returns the number of bytes obtained from the
1454
system for this space.
1455
*/
1456
DLMALLOC_EXPORT size_t mspace_footprint(mspace msp);
1457
1458
/*
1459
mspace_max_footprint() returns the peak number of bytes obtained from the
1460
system for this space.
1461
*/
1462
DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp);
1463
1464
1465
#if !NO_MALLINFO
1466
/*
1467
mspace_mallinfo behaves as mallinfo, but reports properties of
1468
the given space.
1469
*/
1470
DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp);
1471
#endif /* NO_MALLINFO */
1472
1473
/*
1474
malloc_usable_size(void* p) behaves the same as malloc_usable_size;
1475
*/
1476
DLMALLOC_EXPORT size_t mspace_usable_size(const void* mem);
1477
1478
/*
1479
mspace_malloc_stats behaves as malloc_stats, but reports
1480
properties of the given space.
1481
*/
1482
DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp);
1483
1484
/*
1485
mspace_trim behaves as malloc_trim, but
1486
operates within the given space.
1487
*/
1488
DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad);
1489
1490
/*
1491
An alias for mallopt.
1492
*/
1493
DLMALLOC_EXPORT int mspace_mallopt(int, int);
1494
1495
#endif /* MSPACES */
1496
1497
#ifdef __cplusplus
1498
} /* end of extern "C" */
1499
#endif /* __cplusplus */
1500
1501
/*
1502
========================================================================
1503
To make a fully customizable malloc.h header file, cut everything
1504
above this line, put into file malloc.h, edit to suit, and #include it
1505
on the next line, as well as in programs that use this malloc.
1506
========================================================================
1507
*/
1508
1509
/* #include "malloc.h" */
1510
1511
/*------------------------------ internal #includes ---------------------- */
1512
1513
#ifdef _MSC_VER
1514
#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
1515
#endif /* _MSC_VER */
1516
#if !NO_MALLOC_STATS
1517
#include <stdio.h> /* for printing in malloc_stats */
1518
#endif /* NO_MALLOC_STATS */
1519
#ifndef LACKS_ERRNO_H
1520
#include <errno.h> /* for MALLOC_FAILURE_ACTION */
1521
#endif /* LACKS_ERRNO_H */
1522
#ifdef DEBUG
1523
#if ABORT_ON_ASSERT_FAILURE
1524
#undef assert
1525
#define assert(x) if(!(x)) ABORT
1526
#else /* ABORT_ON_ASSERT_FAILURE */
1527
#include <assert.h>
1528
#endif /* ABORT_ON_ASSERT_FAILURE */
1529
#else /* DEBUG */
1530
#ifndef assert
1531
#define assert(x)
1532
#endif
1533
#define DEBUG 0
1534
#endif /* DEBUG */
1535
#if !defined(WIN32) && !defined(LACKS_TIME_H)
1536
#include <time.h> /* for magic initialization */
1537
#endif /* WIN32 */
1538
#ifndef LACKS_STDLIB_H
1539
#include <stdlib.h> /* for abort() */
1540
#endif /* LACKS_STDLIB_H */
1541
#ifndef LACKS_STRING_H
1542
#include <string.h> /* for memset etc */
1543
#endif /* LACKS_STRING_H */
1544
#if USE_BUILTIN_FFS
1545
#ifndef LACKS_STRINGS_H
1546
#include <strings.h> /* for ffs */
1547
#endif /* LACKS_STRINGS_H */
1548
#endif /* USE_BUILTIN_FFS */
1549
#if HAVE_MMAP
1550
#ifndef LACKS_SYS_MMAN_H
1551
/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */
1552
#if (defined(linux) && !defined(__USE_GNU))
1553
#define __USE_GNU 1
1554
#include <sys/mman.h> /* for mmap */
1555
#undef __USE_GNU
1556
#else
1557
#include <sys/mman.h> /* for mmap */
1558
#endif /* linux */
1559
#endif /* LACKS_SYS_MMAN_H */
1560
#ifndef LACKS_FCNTL_H
1561
#include <fcntl.h>
1562
#endif /* LACKS_FCNTL_H */
1563
#endif /* HAVE_MMAP */
1564
#ifndef LACKS_UNISTD_H
1565
#include <unistd.h> /* for sbrk, sysconf */
1566
#else /* LACKS_UNISTD_H */
1567
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
1568
extern void* sbrk(ptrdiff_t);
1569
#endif /* FreeBSD etc */
1570
#endif /* LACKS_UNISTD_H */
1571
1572
/* Declarations for locking */
1573
#if USE_LOCKS
1574
#ifndef WIN32
1575
#if defined (__SVR4) && defined (__sun) /* solaris */
1576
#include <thread.h>
1577
#elif !defined(LACKS_SCHED_H)
1578
#include <sched.h>
1579
#endif /* solaris or LACKS_SCHED_H */
1580
#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS
1581
#include <pthread.h>
1582
#endif /* USE_RECURSIVE_LOCKS ... */
1583
#elif defined(_MSC_VER)
1584
#ifndef _M_AMD64
1585
/* These are already defined on AMD64 builds */
1586
#ifdef __cplusplus
1587
extern "C" {
1588
#endif /* __cplusplus */
1589
LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);
1590
LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
1591
#ifdef __cplusplus
1592
}
1593
#endif /* __cplusplus */
1594
#endif /* _M_AMD64 */
1595
#pragma intrinsic (_InterlockedCompareExchange)
1596
#pragma intrinsic (_InterlockedExchange)
1597
#define interlockedcompareexchange _InterlockedCompareExchange
1598
#define interlockedexchange _InterlockedExchange
1599
#elif defined(WIN32) && defined(__GNUC__)
1600
#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
1601
#define interlockedexchange __sync_lock_test_and_set
1602
#endif /* Win32 */
1603
#else /* USE_LOCKS */
1604
#endif /* USE_LOCKS */
1605
1606
#ifndef LOCK_AT_FORK
1607
#define LOCK_AT_FORK 0
1608
#endif
1609
1610
/* Declarations for bit scanning on win32 */
1611
#if defined(_MSC_VER) && _MSC_VER>=1300
1612
#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */
1613
#ifdef __cplusplus
1614
extern "C" {
1615
#endif /* __cplusplus */
1616
unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
1617
unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
1618
#ifdef __cplusplus
1619
}
1620
#endif /* __cplusplus */
1621
1622
#define BitScanForward _BitScanForward
1623
#define BitScanReverse _BitScanReverse
1624
#pragma intrinsic(_BitScanForward)
1625
#pragma intrinsic(_BitScanReverse)
1626
#endif /* BitScanForward */
1627
#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */
1628
1629
#ifndef WIN32
1630
#ifndef malloc_getpagesize
1631
# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */
1632
# ifndef _SC_PAGE_SIZE
1633
# define _SC_PAGE_SIZE _SC_PAGESIZE
1634
# endif
1635
# endif
1636
# ifdef _SC_PAGE_SIZE
1637
# if defined(__EMSCRIPTEN__)
1638
# define malloc_getpagesize (4096) /* avoid sysconf calls during startup */
1639
# else
1640
# define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
1641
# endif
1642
# else
1643
# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
1644
extern size_t getpagesize();
1645
# define malloc_getpagesize getpagesize()
1646
# else
1647
# ifdef WIN32 /* use supplied emulation of getpagesize */
1648
# define malloc_getpagesize getpagesize()
1649
# else
1650
# ifndef LACKS_SYS_PARAM_H
1651
# include <sys/param.h>
1652
# endif
1653
# ifdef EXEC_PAGESIZE
1654
# define malloc_getpagesize EXEC_PAGESIZE
1655
# else
1656
# ifdef NBPG
1657
# ifndef CLSIZE
1658
# define malloc_getpagesize NBPG
1659
# else
1660
# define malloc_getpagesize (NBPG * CLSIZE)
1661
# endif
1662
# else
1663
# ifdef NBPC
1664
# define malloc_getpagesize NBPC
1665
# else
1666
# ifdef PAGESIZE
1667
# define malloc_getpagesize PAGESIZE
1668
# else /* just guess */
1669
# define malloc_getpagesize ((size_t)4096U)
1670
# endif
1671
# endif
1672
# endif
1673
# endif
1674
# endif
1675
# endif
1676
# endif
1677
#endif
1678
#endif
1679
1680
/* ------------------- size_t and alignment properties -------------------- */
1681
1682
/* The byte and bit size of a size_t */
1683
#define SIZE_T_SIZE (sizeof(size_t))
1684
#define SIZE_T_BITSIZE (sizeof(size_t) << 3)
1685
1686
/* Some constants coerced to size_t */
1687
/* Annoying but necessary to avoid errors on some platforms */
1688
#define SIZE_T_ZERO ((size_t)0)
1689
#define SIZE_T_ONE ((size_t)1)
1690
#define SIZE_T_TWO ((size_t)2)
1691
#define SIZE_T_FOUR ((size_t)4)
1692
#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1)
1693
#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2)
1694
#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
1695
#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U)
1696
1697
/* The bit mask value corresponding to MALLOC_ALIGNMENT */
1698
#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
1699
1700
/* True if address a has acceptable alignment */
1701
#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
1702
1703
/* the number of bytes to offset an address to align it */
1704
#define align_offset(A)\
1705
((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
1706
((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
1707
1708
/* -------------------------- MMAP preliminaries ------------------------- */
1709
1710
/*
1711
If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
1712
checks to fail so compiler optimizer can delete code rather than
1713
using so many "#if"s.
1714
*/
1715
1716
1717
/* MORECORE and MMAP must return MFAIL on failure */
1718
#define MFAIL ((void*)(MAX_SIZE_T))
1719
#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */
1720
1721
#if HAVE_MMAP
1722
1723
#ifndef WIN32
1724
#define MUNMAP_DEFAULT(a, s) munmap((a), (s))
1725
#define MMAP_PROT (PROT_READ|PROT_WRITE)
1726
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
1727
#define MAP_ANONYMOUS MAP_ANON
1728
#endif /* MAP_ANON */
1729
#ifdef MAP_ANONYMOUS
1730
#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
1731
#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
1732
#else /* MAP_ANONYMOUS */
1733
/*
1734
Nearly all versions of mmap support MAP_ANONYMOUS, so the following
1735
is unlikely to be needed, but is supplied just in case.
1736
*/
1737
#define MMAP_FLAGS (MAP_PRIVATE)
1738
static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
1739
#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \
1740
(dev_zero_fd = open("/dev/zero", O_RDWR), \
1741
mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
1742
mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
1743
#endif /* MAP_ANONYMOUS */
1744
1745
#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)
1746
1747
#else /* WIN32 */
1748
1749
/* Win32 MMAP via VirtualAlloc */
1750
static FORCEINLINE void* win32mmap(size_t size) {
1751
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
1752
return (ptr != 0)? ptr: MFAIL;
1753
}
1754
1755
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
1756
static FORCEINLINE void* win32direct_mmap(size_t size) {
1757
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
1758
PAGE_READWRITE);
1759
return (ptr != 0)? ptr: MFAIL;
1760
}
1761
1762
/* This function supports releasing coalesed segments */
1763
static FORCEINLINE int win32munmap(void* ptr, size_t size) {
1764
MEMORY_BASIC_INFORMATION minfo;
1765
char* cptr = (char*)ptr;
1766
while (size) {
1767
if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
1768
return -1;
1769
if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
1770
minfo.State != MEM_COMMIT || minfo.RegionSize > size)
1771
return -1;
1772
if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
1773
return -1;
1774
cptr += minfo.RegionSize;
1775
size -= minfo.RegionSize;
1776
}
1777
return 0;
1778
}
1779
1780
#define MMAP_DEFAULT(s) win32mmap(s)
1781
#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s))
1782
#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s)
1783
#endif /* WIN32 */
1784
#endif /* HAVE_MMAP */
1785
1786
#if HAVE_MREMAP
1787
#ifndef WIN32
1788
#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
1789
#endif /* WIN32 */
1790
#endif /* HAVE_MREMAP */
1791
1792
/**
1793
* Define CALL_MORECORE
1794
*/
1795
#if HAVE_MORECORE
1796
#ifdef MORECORE
1797
#define CALL_MORECORE(S) MORECORE(S)
1798
#else /* MORECORE */
1799
#define CALL_MORECORE(S) MORECORE_DEFAULT(S)
1800
#endif /* MORECORE */
1801
#else /* HAVE_MORECORE */
1802
#define CALL_MORECORE(S) MFAIL
1803
#endif /* HAVE_MORECORE */
1804
1805
/**
1806
* Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP
1807
*/
1808
#if HAVE_MMAP
1809
#define USE_MMAP_BIT (SIZE_T_ONE)
1810
1811
#ifdef MMAP
1812
#define CALL_MMAP(s) MMAP(s)
1813
#else /* MMAP */
1814
#define CALL_MMAP(s) MMAP_DEFAULT(s)
1815
#endif /* MMAP */
1816
#ifdef MUNMAP
1817
#define CALL_MUNMAP(a, s) MUNMAP((a), (s))
1818
#else /* MUNMAP */
1819
#define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s))
1820
#endif /* MUNMAP */
1821
#ifdef DIRECT_MMAP
1822
#define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
1823
#else /* DIRECT_MMAP */
1824
#define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)
1825
#endif /* DIRECT_MMAP */
1826
#else /* HAVE_MMAP */
1827
#define USE_MMAP_BIT (SIZE_T_ZERO)
1828
1829
#define MMAP(s) MFAIL
1830
#define MUNMAP(a, s) (-1)
1831
#define DIRECT_MMAP(s) MFAIL
1832
#define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
1833
#define CALL_MMAP(s) MMAP(s)
1834
#define CALL_MUNMAP(a, s) MUNMAP((a), (s))
1835
#endif /* HAVE_MMAP */
1836
1837
/**
1838
* Define CALL_MREMAP
1839
*/
1840
#if HAVE_MMAP && HAVE_MREMAP
1841
#ifdef MREMAP
1842
#define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))
1843
#else /* MREMAP */
1844
#define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))
1845
#endif /* MREMAP */
1846
#else /* HAVE_MMAP && HAVE_MREMAP */
1847
#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL
1848
#endif /* HAVE_MMAP && HAVE_MREMAP */
1849
1850
/* mstate bit set if continguous morecore disabled or failed */
1851
#define USE_NONCONTIGUOUS_BIT (4U)
1852
1853
/* segment bit set in create_mspace_with_base */
1854
#define EXTERN_BIT (8U)
1855
1856
1857
/* --------------------------- Lock preliminaries ------------------------ */
1858
1859
/*
1860
When locks are defined, there is one global lock, plus
1861
one per-mspace lock.
1862
1863
The global lock_ensures that mparams.magic and other unique
1864
mparams values are initialized only once. It also protects
1865
sequences of calls to MORECORE. In many cases sys_alloc requires
1866
two calls, that should not be interleaved with calls by other
1867
threads. This does not protect against direct calls to MORECORE
1868
by other threads not using this lock, so there is still code to
1869
cope the best we can on interference.
1870
1871
Per-mspace locks surround calls to malloc, free, etc.
1872
By default, locks are simple non-reentrant mutexes.
1873
1874
Because lock-protected regions generally have bounded times, it is
1875
OK to use the supplied simple spinlocks. Spinlocks are likely to
1876
improve performance for lightly contended applications, but worsen
1877
performance under heavy contention.
1878
1879
If USE_LOCKS is > 1, the definitions of lock routines here are
1880
bypassed, in which case you will need to define the type MLOCK_T,
1881
and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK
1882
and TRY_LOCK. You must also declare a
1883
static MLOCK_T malloc_global_mutex = { initialization values };.
1884
1885
*/
1886
1887
#if !USE_LOCKS
1888
#define USE_LOCK_BIT (0U)
1889
#define INITIAL_LOCK(l) (0)
1890
#define DESTROY_LOCK(l) (0)
1891
#define ACQUIRE_MALLOC_GLOBAL_LOCK()
1892
#define RELEASE_MALLOC_GLOBAL_LOCK()
1893
1894
#else
1895
#if USE_LOCKS > 1
1896
/* ----------------------- User-defined locks ------------------------ */
1897
/* Define your own lock implementation here */
1898
/* #define INITIAL_LOCK(lk) ... */
1899
/* #define DESTROY_LOCK(lk) ... */
1900
/* #define ACQUIRE_LOCK(lk) ... */
1901
/* #define RELEASE_LOCK(lk) ... */
1902
/* #define TRY_LOCK(lk) ... */
1903
/* static MLOCK_T malloc_global_mutex = ... */
1904
1905
#elif USE_SPIN_LOCKS
1906
1907
/* First, define CAS_LOCK and CLEAR_LOCK on ints */
1908
/* Note CAS_LOCK defined to return 0 on success */
1909
1910
#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
1911
#define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1)
1912
#define CLEAR_LOCK(sl) __sync_lock_release(sl)
1913
1914
#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
1915
/* Custom spin locks for older gcc on x86 */
1916
static FORCEINLINE int x86_cas_lock(int *sl) {
1917
int ret;
1918
int val = 1;
1919
int cmp = 0;
1920
__asm__ __volatile__ ("lock; cmpxchgl %1, %2"
1921
: "=a" (ret)
1922
: "r" (val), "m" (*(sl)), "0"(cmp)
1923
: "memory", "cc");
1924
return ret;
1925
}
1926
1927
static FORCEINLINE void x86_clear_lock(int* sl) {
1928
assert(*sl != 0);
1929
int prev = 0;
1930
int ret;
1931
__asm__ __volatile__ ("lock; xchgl %0, %1"
1932
: "=r" (ret)
1933
: "m" (*(sl)), "0"(prev)
1934
: "memory");
1935
}
1936
1937
#define CAS_LOCK(sl) x86_cas_lock(sl)
1938
#define CLEAR_LOCK(sl) x86_clear_lock(sl)
1939
1940
#else /* Win32 MSC */
1941
#define CAS_LOCK(sl) interlockedexchange(sl, (LONG)1)
1942
#define CLEAR_LOCK(sl) interlockedexchange (sl, (LONG)0)
1943
1944
#endif /* ... gcc spins locks ... */
1945
1946
/* How to yield for a spin lock */
1947
#define SPINS_PER_YIELD 63
1948
#if defined(_MSC_VER)
1949
#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */
1950
#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE)
1951
#elif defined (__SVR4) && defined (__sun) /* solaris */
1952
#define SPIN_LOCK_YIELD thr_yield();
1953
#elif !defined(LACKS_SCHED_H)
1954
#define SPIN_LOCK_YIELD sched_yield();
1955
#else
1956
#define SPIN_LOCK_YIELD
1957
#endif /* ... yield ... */
1958
1959
#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0
1960
/* Plain spin locks use single word (embedded in malloc_states) */
1961
static int spin_acquire_lock(int *sl) {
1962
int spins = 0;
1963
while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {
1964
if ((++spins & SPINS_PER_YIELD) == 0) {
1965
SPIN_LOCK_YIELD;
1966
}
1967
}
1968
return 0;
1969
}
1970
1971
#define MLOCK_T int
1972
#define TRY_LOCK(sl) !CAS_LOCK(sl)
1973
#define RELEASE_LOCK(sl) CLEAR_LOCK(sl)
1974
#define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0)
1975
#define INITIAL_LOCK(sl) (*sl = 0)
1976
#define DESTROY_LOCK(sl) (0)
1977
static MLOCK_T malloc_global_mutex = 0;
1978
1979
#else /* USE_RECURSIVE_LOCKS */
1980
/* types for lock owners */
1981
#ifdef WIN32
1982
#define THREAD_ID_T DWORD
1983
#define CURRENT_THREAD GetCurrentThreadId()
1984
#define EQ_OWNER(X,Y) ((X) == (Y))
1985
#else
1986
/*
1987
Note: the following assume that pthread_t is a type that can be
1988
initialized to (casted) zero. If this is not the case, you will need to
1989
somehow redefine these or not use spin locks.
1990
*/
1991
#define THREAD_ID_T pthread_t
1992
#define CURRENT_THREAD pthread_self()
1993
#define EQ_OWNER(X,Y) pthread_equal(X, Y)
1994
#endif
1995
1996
struct malloc_recursive_lock {
1997
int sl;
1998
unsigned int c;
1999
THREAD_ID_T threadid;
2000
};
2001
2002
#define MLOCK_T struct malloc_recursive_lock
2003
static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0};
2004
2005
static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {
2006
assert(lk->sl != 0);
2007
if (--lk->c == 0) {
2008
CLEAR_LOCK(&lk->sl);
2009
}
2010
}
2011
2012
static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {
2013
THREAD_ID_T mythreadid = CURRENT_THREAD;
2014
int spins = 0;
2015
for (;;) {
2016
if (*((volatile int *)(&lk->sl)) == 0) {
2017
if (!CAS_LOCK(&lk->sl)) {
2018
lk->threadid = mythreadid;
2019
lk->c = 1;
2020
return 0;
2021
}
2022
}
2023
else if (EQ_OWNER(lk->threadid, mythreadid)) {
2024
++lk->c;
2025
return 0;
2026
}
2027
if ((++spins & SPINS_PER_YIELD) == 0) {
2028
SPIN_LOCK_YIELD;
2029
}
2030
}
2031
}
2032
2033
static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {
2034
THREAD_ID_T mythreadid = CURRENT_THREAD;
2035
if (*((volatile int *)(&lk->sl)) == 0) {
2036
if (!CAS_LOCK(&lk->sl)) {
2037
lk->threadid = mythreadid;
2038
lk->c = 1;
2039
return 1;
2040
}
2041
}
2042
else if (EQ_OWNER(lk->threadid, mythreadid)) {
2043
++lk->c;
2044
return 1;
2045
}
2046
return 0;
2047
}
2048
2049
#define RELEASE_LOCK(lk) recursive_release_lock(lk)
2050
#define TRY_LOCK(lk) recursive_try_lock(lk)
2051
#define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk)
2052
#define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0)
2053
#define DESTROY_LOCK(lk) (0)
2054
#endif /* USE_RECURSIVE_LOCKS */
2055
2056
#elif defined(WIN32) /* Win32 critical sections */
2057
#define MLOCK_T CRITICAL_SECTION
2058
#define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0)
2059
#define RELEASE_LOCK(lk) LeaveCriticalSection(lk)
2060
#define TRY_LOCK(lk) TryEnterCriticalSection(lk)
2061
#define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000))
2062
#define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0)
2063
#define NEED_GLOBAL_LOCK_INIT
2064
2065
static MLOCK_T malloc_global_mutex;
2066
static volatile LONG malloc_global_mutex_status;
2067
2068
/* Use spin loop to initialize global lock */
2069
static void init_malloc_global_mutex() {
2070
for (;;) {
2071
long stat = malloc_global_mutex_status;
2072
if (stat > 0)
2073
return;
2074
/* transition to < 0 while initializing, then to > 0) */
2075
if (stat == 0 &&
2076
interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) {
2077
InitializeCriticalSection(&malloc_global_mutex);
2078
interlockedexchange(&malloc_global_mutex_status, (LONG)1);
2079
return;
2080
}
2081
SleepEx(0, FALSE);
2082
}
2083
}
2084
2085
#else /* pthreads-based locks */
2086
2087
#define MLOCK_T pthread_mutex_t
2088
#define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk)
2089
#define RELEASE_LOCK(lk) pthread_mutex_unlock(lk)
2090
#define TRY_LOCK(lk) (!pthread_mutex_trylock(lk))
2091
#define INITIAL_LOCK(lk) pthread_init_lock(lk)
2092
#define DESTROY_LOCK(lk) pthread_mutex_destroy(lk)
2093
2094
#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE)
2095
/* Cope with old-style linux recursive lock initialization by adding */
2096
/* skipped internal declaration from pthread.h */
2097
extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,
2098
int __kind));
2099
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
2100
#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)
2101
#endif /* USE_RECURSIVE_LOCKS ... */
2102
2103
static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;
2104
2105
static int pthread_init_lock (MLOCK_T *lk) {
2106
pthread_mutexattr_t attr;
2107
if (pthread_mutexattr_init(&attr)) return 1;
2108
#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0
2109
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;
2110
#endif
2111
if (pthread_mutex_init(lk, &attr)) return 1;
2112
if (pthread_mutexattr_destroy(&attr)) return 1;
2113
return 0;
2114
}
2115
2116
#endif /* ... lock types ... */
2117
2118
/* Common code for all lock types */
2119
#define USE_LOCK_BIT (2U)
2120
2121
#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK
2122
#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex);
2123
#endif
2124
2125
#ifndef RELEASE_MALLOC_GLOBAL_LOCK
2126
#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex);
2127
#endif
2128
2129
#endif /* USE_LOCKS */
2130
2131
/* ----------------------- Chunk representations ------------------------ */
2132
2133
/*
2134
(The following includes lightly edited explanations by Colin Plumb.)
2135
2136
The malloc_chunk declaration below is misleading (but accurate and
2137
necessary). It declares a "view" into memory allowing access to
2138
necessary fields at known offsets from a given base.
2139
2140
Chunks of memory are maintained using a `boundary tag' method as
2141
originally described by Knuth. (See the paper by Paul Wilson
2142
ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
2143
techniques.) Sizes of free chunks are stored both in the front of
2144
each chunk and at the end. This makes consolidating fragmented
2145
chunks into bigger chunks fast. The head fields also hold bits
2146
representing whether chunks are free or in use.
2147
2148
Here are some pictures to make it clearer. They are "exploded" to
2149
show that the state of a chunk can be thought of as extending from
2150
the high 31 bits of the head field of its header through the
2151
prev_foot and PINUSE_BIT bit of the following chunk header.
2152
2153
A chunk that's in use looks like:
2154
2155
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2156
| Size of previous chunk (if P = 0) |
2157
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2158
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
2159
| Size of this chunk 1| +-+
2160
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2161
| |
2162
+- -+
2163
| |
2164
+- -+
2165
| :
2166
+- size - sizeof(size_t) available payload bytes -+
2167
: |
2168
chunk-> +- -+
2169
| |
2170
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2171
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
2172
| Size of next chunk (may or may not be in use) | +-+
2173
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2174
2175
And if it's free, it looks like this:
2176
2177
chunk-> +- -+
2178
| User payload (must be in use, or we would have merged!) |
2179
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2180
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
2181
| Size of this chunk 0| +-+
2182
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2183
| Next pointer |
2184
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2185
| Prev pointer |
2186
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2187
| :
2188
+- size - sizeof(struct chunk) unused bytes -+
2189
: |
2190
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2191
| Size of this chunk |
2192
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2193
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
2194
| Size of next chunk (must be in use, or we would have merged)| +-+
2195
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2196
| :
2197
+- User payload -+
2198
: |
2199
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2200
|0|
2201
+-+
2202
Note that since we always merge adjacent free chunks, the chunks
2203
adjacent to a free chunk must be in use.
2204
2205
Given a pointer to a chunk (which can be derived trivially from the
2206
payload pointer) we can, in O(1) time, find out whether the adjacent
2207
chunks are free, and if so, unlink them from the lists that they
2208
are on and merge them with the current chunk.
2209
2210
Chunks always begin on even word boundaries, so the mem portion
2211
(which is returned to the user) is also on an even word boundary, and
2212
thus at least double-word aligned.
2213
2214
The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
2215
chunk size (which is always a multiple of two words), is an in-use
2216
bit for the *previous* chunk. If that bit is *clear*, then the
2217
word before the current chunk size contains the previous chunk
2218
size, and can be used to find the front of the previous chunk.
2219
The very first chunk allocated always has this bit set, preventing
2220
access to non-existent (or non-owned) memory. If pinuse is set for
2221
any given chunk, then you CANNOT determine the size of the
2222
previous chunk, and might even get a memory addressing fault when
2223
trying to do so.
2224
2225
The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
2226
the chunk size redundantly records whether the current chunk is
2227
inuse (unless the chunk is mmapped). This redundancy enables usage
2228
checks within free and realloc, and reduces indirection when freeing
2229
and consolidating chunks.
2230
2231
Each freshly allocated chunk must have both cinuse and pinuse set.
2232
That is, each allocated chunk borders either a previously allocated
2233
and still in-use chunk, or the base of its memory arena. This is
2234
ensured by making all allocations from the `lowest' part of any
2235
found chunk. Further, no free chunk physically borders another one,
2236
so each free chunk is known to be preceded and followed by either
2237
inuse chunks or the ends of memory.
2238
2239
Note that the `foot' of the current chunk is actually represented
2240
as the prev_foot of the NEXT chunk. This makes it easier to
2241
deal with alignments etc but can be very confusing when trying
2242
to extend or adapt this code.
2243
2244
The exceptions to all this are
2245
2246
1. The special chunk `top' is the top-most available chunk (i.e.,
2247
the one bordering the end of available memory). It is treated
2248
specially. Top is never included in any bin, is used only if
2249
no other chunk is available, and is released back to the
2250
system if it is very large (see M_TRIM_THRESHOLD). In effect,
2251
the top chunk is treated as larger (and thus less well
2252
fitting) than any other available chunk. The top chunk
2253
doesn't update its trailing size field since there is no next
2254
contiguous chunk that would have to index off it. However,
2255
space is still allocated for it (TOP_FOOT_SIZE) to enable
2256
separation or merging when space is extended.
2257
2258
3. Chunks allocated via mmap, have both cinuse and pinuse bits
2259
cleared in their head fields. Because they are allocated
2260
one-by-one, each must carry its own prev_foot field, which is
2261
also used to hold the offset this chunk has within its mmapped
2262
region, which is needed to preserve alignment. Each mmapped
2263
chunk is trailed by the first two fields of a fake next-chunk
2264
for sake of usage checks.
2265
2266
*/
2267
2268
struct malloc_chunk {
2269
size_t prev_foot; /* Size of previous chunk (if free). */
2270
size_t head; /* Size and inuse bits. */
2271
struct malloc_chunk* fd; /* double links -- used only if free. */
2272
struct malloc_chunk* bk;
2273
};
2274
2275
typedef struct malloc_chunk mchunk;
2276
typedef struct malloc_chunk* mchunkptr;
2277
typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */
2278
typedef unsigned int bindex_t; /* Described below */
2279
typedef unsigned int binmap_t; /* Described below */
2280
typedef unsigned int flag_t; /* The type of various bit flag sets */
2281
2282
/* ------------------- Chunks sizes and alignments ----------------------- */
2283
2284
#define MCHUNK_SIZE (sizeof(mchunk))
2285
2286
#if FOOTERS
2287
#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
2288
#else /* FOOTERS */
2289
#define CHUNK_OVERHEAD (SIZE_T_SIZE)
2290
#endif /* FOOTERS */
2291
2292
/* MMapped chunks need a second word of overhead ... */
2293
#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
2294
/* ... and additional padding for fake next-chunk at foot */
2295
#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES)
2296
2297
/* The smallest size we can malloc is an aligned minimal chunk */
2298
#define MIN_CHUNK_SIZE \
2299
((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
2300
2301
/* conversion from malloc headers to user pointers, and back */
2302
#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES))
2303
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
2304
/* chunk associated with aligned address A */
2305
#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A)))
2306
2307
/* Bounds on request (not chunk) sizes. */
2308
#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2)
2309
#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
2310
2311
/* pad request bytes into a usable size */
2312
#define pad_request(req) \
2313
(((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
2314
2315
/* pad request, checking for minimum (but not maximum) */
2316
#define request2size(req) \
2317
(((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
2318
2319
2320
/* ------------------ Operations on head and foot fields ----------------- */
2321
2322
/*
2323
The head field of a chunk is or'ed with PINUSE_BIT when previous
2324
adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
2325
use, unless mmapped, in which case both bits are cleared.
2326
2327
FLAG4_BIT is not used by this malloc, but might be useful in extensions.
2328
*/
2329
2330
#define PINUSE_BIT (SIZE_T_ONE)
2331
#define CINUSE_BIT (SIZE_T_TWO)
2332
#define FLAG4_BIT (SIZE_T_FOUR)
2333
#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT)
2334
#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)
2335
2336
/* Head value for fenceposts */
2337
#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE)
2338
2339
/* extraction of fields from head words */
2340
#define cinuse(p) ((p)->head & CINUSE_BIT)
2341
#define pinuse(p) ((p)->head & PINUSE_BIT)
2342
#define flag4inuse(p) ((p)->head & FLAG4_BIT)
2343
#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT)
2344
#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0)
2345
2346
#define chunksize(p) ((p)->head & ~(FLAG_BITS))
2347
2348
#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT)
2349
#define set_flag4(p) ((p)->head |= FLAG4_BIT)
2350
#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT)
2351
2352
/* Treat space at ptr +/- offset as a chunk */
2353
#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
2354
#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
2355
2356
/* Ptr to next or previous physical malloc_chunk. */
2357
#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))
2358
#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
2359
2360
/* extract next chunk's pinuse bit */
2361
#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT)
2362
2363
/* Get/set size at footer */
2364
#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot)
2365
#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
2366
2367
/* Set size, pinuse bit, and foot */
2368
#define set_size_and_pinuse_of_free_chunk(p, s)\
2369
((p)->head = (s|PINUSE_BIT), set_foot(p, s))
2370
2371
/* Set size, pinuse bit, foot, and clear next pinuse */
2372
#define set_free_with_pinuse(p, s, n)\
2373
(clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
2374
2375
/* Get the internal overhead associated with chunk p */
2376
#define overhead_for(p)\
2377
(is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
2378
2379
/* Return true if malloced space is not necessarily cleared */
2380
#if MMAP_CLEARS
2381
#define calloc_must_clear(p) (!is_mmapped(p))
2382
#else /* MMAP_CLEARS */
2383
#define calloc_must_clear(p) (1)
2384
#endif /* MMAP_CLEARS */
2385
2386
/* ---------------------- Overlaid data structures ----------------------- */
2387
2388
/*
2389
When chunks are not in use, they are treated as nodes of either
2390
lists or trees.
2391
2392
"Small" chunks are stored in circular doubly-linked lists, and look
2393
like this:
2394
2395
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2396
| Size of previous chunk |
2397
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2398
`head:' | Size of chunk, in bytes |P|
2399
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2400
| Forward pointer to next chunk in list |
2401
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2402
| Back pointer to previous chunk in list |
2403
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2404
| Unused space (may be 0 bytes long) .
2405
. .
2406
. |
2407
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2408
`foot:' | Size of chunk, in bytes |
2409
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2410
2411
Larger chunks are kept in a form of bitwise digital trees (aka
2412
tries) keyed on chunksizes. Because malloc_tree_chunks are only for
2413
free chunks greater than 256 bytes, their size doesn't impose any
2414
constraints on user chunk sizes. Each node looks like:
2415
2416
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2417
| Size of previous chunk |
2418
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2419
`head:' | Size of chunk, in bytes |P|
2420
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2421
| Forward pointer to next chunk of same size |
2422
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2423
| Back pointer to previous chunk of same size |
2424
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2425
| Pointer to left child (child[0]) |
2426
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2427
| Pointer to right child (child[1]) |
2428
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2429
| Pointer to parent |
2430
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2431
| bin index of this chunk |
2432
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2433
| Unused space .
2434
. |
2435
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2436
`foot:' | Size of chunk, in bytes |
2437
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2438
2439
Each tree holding treenodes is a tree of unique chunk sizes. Chunks
2440
of the same size are arranged in a circularly-linked list, with only
2441
the oldest chunk (the next to be used, in our FIFO ordering)
2442
actually in the tree. (Tree members are distinguished by a non-null
2443
parent pointer.) If a chunk with the same size an an existing node
2444
is inserted, it is linked off the existing node using pointers that
2445
work in the same way as fd/bk pointers of small chunks.
2446
2447
Each tree contains a power of 2 sized range of chunk sizes (the
2448
smallest is 0x100 <= x < 0x180), which is is divided in half at each
2449
tree level, with the chunks in the smaller half of the range (0x100
2450
<= x < 0x140 for the top nose) in the left subtree and the larger
2451
half (0x140 <= x < 0x180) in the right subtree. This is, of course,
2452
done by inspecting individual bits.
2453
2454
Using these rules, each node's left subtree contains all smaller
2455
sizes than its right subtree. However, the node at the root of each
2456
subtree has no particular ordering relationship to either. (The
2457
dividing line between the subtree sizes is based on trie relation.)
2458
If we remove the last chunk of a given size from the interior of the
2459
tree, we need to replace it with a leaf node. The tree ordering
2460
rules permit a node to be replaced by any leaf below it.
2461
2462
The smallest chunk in a tree (a common operation in a best-fit
2463
allocator) can be found by walking a path to the leftmost leaf in
2464
the tree. Unlike a usual binary tree, where we follow left child
2465
pointers until we reach a null, here we follow the right child
2466
pointer any time the left one is null, until we reach a leaf with
2467
both child pointers null. The smallest chunk in the tree will be
2468
somewhere along that path.
2469
2470
The worst case number of steps to add, find, or remove a node is
2471
bounded by the number of bits differentiating chunks within
2472
bins. Under current bin calculations, this ranges from 6 up to 21
2473
(for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
2474
is of course much better.
2475
*/
2476
2477
struct malloc_tree_chunk {
2478
/* The first four fields must be compatible with malloc_chunk */
2479
size_t prev_foot;
2480
size_t head;
2481
struct malloc_tree_chunk* fd;
2482
struct malloc_tree_chunk* bk;
2483
2484
struct malloc_tree_chunk* child[2];
2485
struct malloc_tree_chunk* parent;
2486
bindex_t index;
2487
};
2488
2489
typedef struct malloc_tree_chunk tchunk;
2490
typedef struct malloc_tree_chunk* tchunkptr;
2491
typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
2492
2493
/* A little helper macro for trees */
2494
#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
2495
2496
/* ----------------------------- Segments -------------------------------- */
2497
2498
/*
2499
Each malloc space may include non-contiguous segments, held in a
2500
list headed by an embedded malloc_segment record representing the
2501
top-most space. Segments also include flags holding properties of
2502
the space. Large chunks that are directly allocated by mmap are not
2503
included in this list. They are instead independently created and
2504
destroyed without otherwise keeping track of them.
2505
2506
Segment management mainly comes into play for spaces allocated by
2507
MMAP. Any call to MMAP might or might not return memory that is
2508
adjacent to an existing segment. MORECORE normally contiguously
2509
extends the current space, so this space is almost always adjacent,
2510
which is simpler and faster to deal with. (This is why MORECORE is
2511
used preferentially to MMAP when both are available -- see
2512
sys_alloc.) When allocating using MMAP, we don't use any of the
2513
hinting mechanisms (inconsistently) supported in various
2514
implementations of unix mmap, or distinguish reserving from
2515
committing memory. Instead, we just ask for space, and exploit
2516
contiguity when we get it. It is probably possible to do
2517
better than this on some systems, but no general scheme seems
2518
to be significantly better.
2519
2520
Management entails a simpler variant of the consolidation scheme
2521
used for chunks to reduce fragmentation -- new adjacent memory is
2522
normally prepended or appended to an existing segment. However,
2523
there are limitations compared to chunk consolidation that mostly
2524
reflect the fact that segment processing is relatively infrequent
2525
(occurring only when getting memory from system) and that we
2526
don't expect to have huge numbers of segments:
2527
2528
* Segments are not indexed, so traversal requires linear scans. (It
2529
would be possible to index these, but is not worth the extra
2530
overhead and complexity for most programs on most platforms.)
2531
* New segments are only appended to old ones when holding top-most
2532
memory; if they cannot be prepended to others, they are held in
2533
different segments.
2534
2535
Except for the top-most segment of an mstate, each segment record
2536
is kept at the tail of its segment. Segments are added by pushing
2537
segment records onto the list headed by &mstate.seg for the
2538
containing mstate.
2539
2540
Segment flags control allocation/merge/deallocation policies:
2541
* If EXTERN_BIT set, then we did not allocate this segment,
2542
and so should not try to deallocate or merge with others.
2543
(This currently holds only for the initial segment passed
2544
into create_mspace_with_base.)
2545
* If USE_MMAP_BIT set, the segment may be merged with
2546
other surrounding mmapped segments and trimmed/de-allocated
2547
using munmap.
2548
* If neither bit is set, then the segment was obtained using
2549
MORECORE so can be merged with surrounding MORECORE'd segments
2550
and deallocated/trimmed using MORECORE with negative arguments.
2551
*/
2552
2553
struct malloc_segment {
2554
char* base; /* base address */
2555
size_t size; /* allocated size */
2556
struct malloc_segment* next; /* ptr to next segment */
2557
flag_t sflags; /* mmap and extern flag */
2558
};
2559
2560
#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT)
2561
#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT)
2562
2563
typedef struct malloc_segment msegment;
2564
typedef struct malloc_segment* msegmentptr;
2565
2566
/* ---------------------------- malloc_state ----------------------------- */
2567
2568
/*
2569
A malloc_state holds all of the bookkeeping for a space.
2570
The main fields are:
2571
2572
Top
2573
The topmost chunk of the currently active segment. Its size is
2574
cached in topsize. The actual size of topmost space is
2575
topsize+TOP_FOOT_SIZE, which includes space reserved for adding
2576
fenceposts and segment records if necessary when getting more
2577
space from the system. The size at which to autotrim top is
2578
cached from mparams in trim_check, except that it is disabled if
2579
an autotrim fails.
2580
2581
Designated victim (dv)
2582
This is the preferred chunk for servicing small requests that
2583
don't have exact fits. It is normally the chunk split off most
2584
recently to service another small request. Its size is cached in
2585
dvsize. The link fields of this chunk are not maintained since it
2586
is not kept in a bin.
2587
2588
SmallBins
2589
An array of bin headers for free chunks. These bins hold chunks
2590
with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
2591
chunks of all the same size, spaced 8 bytes apart. To simplify
2592
use in double-linked lists, each bin header acts as a malloc_chunk
2593
pointing to the real first node, if it exists (else pointing to
2594
itself). This avoids special-casing for headers. But to avoid
2595
waste, we allocate only the fd/bk pointers of bins, and then use
2596
repositioning tricks to treat these as the fields of a chunk.
2597
2598
TreeBins
2599
Treebins are pointers to the roots of trees holding a range of
2600
sizes. There are 2 equally spaced treebins for each power of two
2601
from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
2602
larger.
2603
2604
Bin maps
2605
There is one bit map for small bins ("smallmap") and one for
2606
treebins ("treemap). Each bin sets its bit when non-empty, and
2607
clears the bit when empty. Bit operations are then used to avoid
2608
bin-by-bin searching -- nearly all "search" is done without ever
2609
looking at bins that won't be selected. The bit maps
2610
conservatively use 32 bits per map word, even if on 64bit system.
2611
For a good description of some of the bit-based techniques used
2612
here, see Henry S. Warren Jr's book "Hacker's Delight" (and
2613
supplement at http://hackersdelight.org/). Many of these are
2614
intended to reduce the branchiness of paths through malloc etc, as
2615
well as to reduce the number of memory locations read or written.
2616
2617
Segments
2618
A list of segments headed by an embedded malloc_segment record
2619
representing the initial space.
2620
2621
Address check support
2622
The least_addr field is the least address ever obtained from
2623
MORECORE or MMAP. Attempted frees and reallocs of any address less
2624
than this are trapped (unless INSECURE is defined).
2625
2626
Magic tag
2627
A cross-check field that should always hold same value as mparams.magic.
2628
2629
Max allowed footprint
2630
The maximum allowed bytes to allocate from system (zero means no limit)
2631
2632
Flags
2633
Bits recording whether to use MMAP, locks, or contiguous MORECORE
2634
2635
Statistics
2636
Each space keeps track of current and maximum system memory
2637
obtained via MORECORE or MMAP.
2638
2639
Trim support
2640
Fields holding the amount of unused topmost memory that should trigger
2641
trimming, and a counter to force periodic scanning to release unused
2642
non-topmost segments.
2643
2644
Locking
2645
If USE_LOCKS is defined, the "mutex" lock is acquired and released
2646
around every public call using this mspace.
2647
2648
Extension support
2649
A void* pointer and a size_t field that can be used to help implement
2650
extensions to this malloc.
2651
*/
2652
2653
/* Bin types, widths and sizes */
2654
#define NSMALLBINS (32U)
2655
#define NTREEBINS (32U)
2656
#define SMALLBIN_SHIFT (3U)
2657
#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT)
2658
#define TREEBIN_SHIFT (8U)
2659
#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT)
2660
#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE)
2661
#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
2662
2663
struct malloc_state {
2664
binmap_t smallmap;
2665
binmap_t treemap;
2666
size_t dvsize;
2667
size_t topsize;
2668
char* least_addr;
2669
mchunkptr dv;
2670
mchunkptr top;
2671
size_t trim_check;
2672
size_t release_checks;
2673
size_t magic;
2674
mchunkptr smallbins[(NSMALLBINS+1)*2];
2675
tbinptr treebins[NTREEBINS];
2676
size_t footprint;
2677
size_t max_footprint;
2678
size_t footprint_limit; /* zero means no limit */
2679
flag_t mflags;
2680
#if USE_LOCKS
2681
MLOCK_T mutex; /* locate lock among fields that rarely change */
2682
#endif /* USE_LOCKS */
2683
msegment seg;
2684
void* extp; /* Unused but available for extensions */
2685
size_t exts;
2686
};
2687
2688
typedef struct malloc_state* mstate;
2689
2690
/* ------------- Global malloc_state and malloc_params ------------------- */
2691
2692
/*
2693
malloc_params holds global properties, including those that can be
2694
dynamically set using mallopt. There is a single instance, mparams,
2695
initialized in init_mparams. Note that the non-zeroness of "magic"
2696
also serves as an initialization flag.
2697
*/
2698
2699
struct malloc_params {
2700
size_t magic;
2701
size_t page_size;
2702
size_t granularity;
2703
size_t mmap_threshold;
2704
size_t trim_threshold;
2705
flag_t default_mflags;
2706
};
2707
2708
static struct malloc_params mparams;
2709
2710
/* Ensure mparams initialized */
2711
#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams())
2712
2713
#if !ONLY_MSPACES
2714
2715
/* The global malloc_state used for all non-"mspace" calls */
2716
static struct malloc_state _gm_;
2717
#define gm (&_gm_)
2718
#define is_global(M) ((M) == &_gm_)
2719
2720
#endif /* !ONLY_MSPACES */
2721
2722
#define is_initialized(M) ((M)->top != 0)
2723
2724
/* -------------------------- system alloc setup ------------------------- */
2725
2726
/* Operations on mflags */
2727
2728
#define use_lock(M) ((M)->mflags & USE_LOCK_BIT)
2729
#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT)
2730
#if USE_LOCKS
2731
#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT)
2732
#else
2733
#define disable_lock(M)
2734
#endif
2735
2736
#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT)
2737
#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT)
2738
#if HAVE_MMAP
2739
#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT)
2740
#else
2741
#define disable_mmap(M)
2742
#endif
2743
2744
#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT)
2745
#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT)
2746
2747
#define set_lock(M,L)\
2748
((M)->mflags = (L)?\
2749
((M)->mflags | USE_LOCK_BIT) :\
2750
((M)->mflags & ~USE_LOCK_BIT))
2751
2752
/* page-align a size */
2753
#define page_align(S)\
2754
(((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))
2755
2756
/* granularity-align a size */
2757
#define granularity_align(S)\
2758
(((S) + (mparams.granularity - SIZE_T_ONE))\
2759
& ~(mparams.granularity - SIZE_T_ONE))
2760
2761
2762
/* For mmap, use granularity alignment on windows, else page-align */
2763
#ifdef WIN32
2764
#define mmap_align(S) granularity_align(S)
2765
#else
2766
#define mmap_align(S) page_align(S)
2767
#endif
2768
2769
/* For sys_alloc, enough padding to ensure can malloc request on success */
2770
#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)
2771
2772
#define is_page_aligned(S)\
2773
(((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
2774
#define is_granularity_aligned(S)\
2775
(((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
2776
2777
/* True if segment S holds address A */
2778
#define segment_holds(S, A)\
2779
((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
2780
2781
/* Return segment holding given address */
2782
static msegmentptr segment_holding(mstate m, char* addr) {
2783
msegmentptr sp = &m->seg;
2784
for (;;) {
2785
if (addr >= sp->base && addr < sp->base + sp->size)
2786
return sp;
2787
if ((sp = sp->next) == 0)
2788
return 0;
2789
}
2790
}
2791
2792
/* Return true if segment contains a segment link */
2793
static int has_segment_link(mstate m, msegmentptr ss) {
2794
msegmentptr sp = &m->seg;
2795
for (;;) {
2796
if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
2797
return 1;
2798
if ((sp = sp->next) == 0)
2799
return 0;
2800
}
2801
}
2802
2803
#ifndef MORECORE_CANNOT_TRIM
2804
#define should_trim(M,s) ((s) > (M)->trim_check)
2805
#else /* MORECORE_CANNOT_TRIM */
2806
#define should_trim(M,s) (0)
2807
#endif /* MORECORE_CANNOT_TRIM */
2808
2809
/*
2810
TOP_FOOT_SIZE is padding at the end of a segment, including space
2811
that may be needed to place segment records and fenceposts when new
2812
noncontiguous segments are added.
2813
*/
2814
#define TOP_FOOT_SIZE \
2815
(align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
2816
2817
2818
/* ------------------------------- Hooks -------------------------------- */
2819
2820
/*
2821
PREACTION should be defined to return 0 on success, and nonzero on
2822
failure. If you are not using locking, you can redefine these to do
2823
anything you like.
2824
*/
2825
2826
#if USE_LOCKS
2827
#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
2828
#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
2829
#else /* USE_LOCKS */
2830
2831
#ifndef PREACTION
2832
#define PREACTION(M) (0)
2833
#endif /* PREACTION */
2834
2835
#ifndef POSTACTION
2836
#define POSTACTION(M)
2837
#endif /* POSTACTION */
2838
2839
#endif /* USE_LOCKS */
2840
2841
/*
2842
CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
2843
USAGE_ERROR_ACTION is triggered on detected bad frees and
2844
reallocs. The argument p is an address that might have triggered the
2845
fault. It is ignored by the two predefined actions, but might be
2846
useful in custom actions that try to help diagnose errors.
2847
*/
2848
2849
#if PROCEED_ON_ERROR
2850
2851
/* A count of the number of corruption errors causing resets */
2852
int malloc_corruption_error_count;
2853
2854
/* default corruption action */
2855
static void reset_on_error(mstate m);
2856
2857
#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m)
2858
#define USAGE_ERROR_ACTION(m, p)
2859
2860
#else /* PROCEED_ON_ERROR */
2861
2862
#ifndef CORRUPTION_ERROR_ACTION
2863
#define CORRUPTION_ERROR_ACTION(m) ABORT
2864
#endif /* CORRUPTION_ERROR_ACTION */
2865
2866
#ifndef USAGE_ERROR_ACTION
2867
#define USAGE_ERROR_ACTION(m,p) ABORT
2868
#endif /* USAGE_ERROR_ACTION */
2869
2870
#endif /* PROCEED_ON_ERROR */
2871
2872
2873
/* -------------------------- Debugging setup ---------------------------- */
2874
2875
#if ! DEBUG
2876
2877
#define check_free_chunk(M,P)
2878
#define check_inuse_chunk(M,P)
2879
#define check_malloced_chunk(M,P,N)
2880
#define check_mmapped_chunk(M,P)
2881
#define check_malloc_state(M)
2882
#define check_top_chunk(M,P)
2883
2884
#else /* DEBUG */
2885
#define check_free_chunk(M,P) do_check_free_chunk(M,P)
2886
#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P)
2887
#define check_top_chunk(M,P) do_check_top_chunk(M,P)
2888
#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
2889
#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P)
2890
#define check_malloc_state(M) do_check_malloc_state(M)
2891
2892
static void do_check_any_chunk(mstate m, mchunkptr p);
2893
static void do_check_top_chunk(mstate m, mchunkptr p);
2894
static void do_check_mmapped_chunk(mstate m, mchunkptr p);
2895
static void do_check_inuse_chunk(mstate m, mchunkptr p);
2896
static void do_check_free_chunk(mstate m, mchunkptr p);
2897
static void do_check_malloced_chunk(mstate m, void* mem, size_t s);
2898
static void do_check_tree(mstate m, tchunkptr t);
2899
static void do_check_treebin(mstate m, bindex_t i);
2900
static void do_check_smallbin(mstate m, bindex_t i);
2901
static void do_check_malloc_state(mstate m);
2902
static int bin_find(mstate m, mchunkptr x);
2903
static size_t traverse_and_check(mstate m);
2904
#endif /* DEBUG */
2905
2906
/* ---------------------------- Indexing Bins ---------------------------- */
2907
2908
#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
2909
#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT)
2910
#define small_index2size(i) ((i) << SMALLBIN_SHIFT)
2911
#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE))
2912
2913
/* addressing by index. See above about smallbin repositioning */
2914
#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
2915
#define treebin_at(M,i) (&((M)->treebins[i]))
2916
2917
/* assign tree index for size S to variable I. Use x86 asm if possible */
2918
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__))
2919
#define compute_tree_index(S, I)\
2920
{\
2921
unsigned int X = S >> TREEBIN_SHIFT;\
2922
if (X == 0)\
2923
I = 0;\
2924
else if (X > 0xFFFF)\
2925
I = NTREEBINS-1;\
2926
else {\
2927
unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \
2928
I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
2929
}\
2930
}
2931
2932
#elif defined (__INTEL_COMPILER)
2933
#define compute_tree_index(S, I)\
2934
{\
2935
size_t X = S >> TREEBIN_SHIFT;\
2936
if (X == 0)\
2937
I = 0;\
2938
else if (X > 0xFFFF)\
2939
I = NTREEBINS-1;\
2940
else {\
2941
unsigned int K = _bit_scan_reverse (X); \
2942
I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
2943
}\
2944
}
2945
2946
#elif defined(_MSC_VER) && _MSC_VER>=1300
2947
#define compute_tree_index(S, I)\
2948
{\
2949
size_t X = S >> TREEBIN_SHIFT;\
2950
if (X == 0)\
2951
I = 0;\
2952
else if (X > 0xFFFF)\
2953
I = NTREEBINS-1;\
2954
else {\
2955
unsigned int K;\
2956
_BitScanReverse((DWORD *) &K, (DWORD) X);\
2957
I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
2958
}\
2959
}
2960
2961
#else /* GNUC */
2962
#define compute_tree_index(S, I)\
2963
{\
2964
size_t X = S >> TREEBIN_SHIFT;\
2965
if (X == 0)\
2966
I = 0;\
2967
else if (X > 0xFFFF)\
2968
I = NTREEBINS-1;\
2969
else {\
2970
unsigned int Y = (unsigned int)X;\
2971
unsigned int N = ((Y - 0x100) >> 16) & 8;\
2972
unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
2973
N += K;\
2974
N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
2975
K = 14 - N + ((Y <<= K) >> 15);\
2976
I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
2977
}\
2978
}
2979
#endif /* GNUC */
2980
2981
/* Bit representing maximum resolved size in a treebin at i */
2982
#define bit_for_tree_index(i) \
2983
(i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
2984
2985
/* Shift placing maximum resolved bit in a treebin at i as sign bit */
2986
#define leftshift_for_tree_index(i) \
2987
((i == NTREEBINS-1)? 0 : \
2988
((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
2989
2990
/* The size of the smallest chunk held in bin with index i */
2991
#define minsize_for_tree_index(i) \
2992
((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \
2993
(((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
2994
2995
2996
/* ------------------------ Operations on bin maps ----------------------- */
2997
2998
/* bit corresponding to given index */
2999
#define idx2bit(i) ((binmap_t)(1) << (i))
3000
3001
/* Mark/Clear bits with given index */
3002
#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i))
3003
#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i))
3004
#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i))
3005
3006
#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i))
3007
#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i))
3008
#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i))
3009
3010
/* isolate the least set bit of a bitmap */
3011
#define least_bit(x) ((x) & -(x))
3012
3013
/* mask with all bits to left of least bit of x on */
3014
#define left_bits(x) ((x<<1) | -(x<<1))
3015
3016
/* mask with all bits to left of or equal to least bit of x on */
3017
#define same_or_left_bits(x) ((x) | -(x))
3018
3019
/* index corresponding to given bit. Use x86 asm if possible */
3020
3021
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__))
3022
#define compute_bit2idx(X, I)\
3023
{\
3024
unsigned int J;\
3025
J = __builtin_ctz(X); \
3026
I = (bindex_t)J;\
3027
}
3028
3029
#elif defined (__INTEL_COMPILER)
3030
#define compute_bit2idx(X, I)\
3031
{\
3032
unsigned int J;\
3033
J = _bit_scan_forward (X); \
3034
I = (bindex_t)J;\
3035
}
3036
3037
#elif defined(_MSC_VER) && _MSC_VER>=1300
3038
#define compute_bit2idx(X, I)\
3039
{\
3040
unsigned int J;\
3041
_BitScanForward((DWORD *) &J, X);\
3042
I = (bindex_t)J;\
3043
}
3044
3045
#elif USE_BUILTIN_FFS
3046
#define compute_bit2idx(X, I) I = ffs(X)-1
3047
3048
#else
3049
#define compute_bit2idx(X, I)\
3050
{\
3051
unsigned int Y = X - 1;\
3052
unsigned int K = Y >> (16-4) & 16;\
3053
unsigned int N = K; Y >>= K;\
3054
N += K = Y >> (8-3) & 8; Y >>= K;\
3055
N += K = Y >> (4-2) & 4; Y >>= K;\
3056
N += K = Y >> (2-1) & 2; Y >>= K;\
3057
N += K = Y >> (1-0) & 1; Y >>= K;\
3058
I = (bindex_t)(N + Y);\
3059
}
3060
#endif /* GNUC */
3061
3062
3063
/* ----------------------- Runtime Check Support ------------------------- */
3064
3065
/*
3066
For security, the main invariant is that malloc/free/etc never
3067
writes to a static address other than malloc_state, unless static
3068
malloc_state itself has been corrupted, which cannot occur via
3069
malloc (because of these checks). In essence this means that we
3070
believe all pointers, sizes, maps etc held in malloc_state, but
3071
check all of those linked or offsetted from other embedded data
3072
structures. These checks are interspersed with main code in a way
3073
that tends to minimize their run-time cost.
3074
3075
When FOOTERS is defined, in addition to range checking, we also
3076
verify footer fields of inuse chunks, which can be used guarantee
3077
that the mstate controlling malloc/free is intact. This is a
3078
streamlined version of the approach described by William Robertson
3079
et al in "Run-time Detection of Heap-based Overflows" LISA'03
3080
http://www.usenix.org/events/lisa03/tech/robertson.html The footer
3081
of an inuse chunk holds the xor of its mstate and a random seed,
3082
that is checked upon calls to free() and realloc(). This is
3083
(probabalistically) unguessable from outside the program, but can be
3084
computed by any code successfully malloc'ing any chunk, so does not
3085
itself provide protection against code that has already broken
3086
security through some other means. Unlike Robertson et al, we
3087
always dynamically check addresses of all offset chunks (previous,
3088
next, etc). This turns out to be cheaper than relying on hashes.
3089
*/
3090
3091
#if !INSECURE
3092
/* Check if address a is at least as high as any from MORECORE or MMAP */
3093
#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
3094
/* Check if address of next chunk n is higher than base chunk p */
3095
#define ok_next(p, n) ((char*)(p) < (char*)(n))
3096
/* Check if p has inuse status */
3097
#define ok_inuse(p) is_inuse(p)
3098
/* Check if p has its pinuse bit on */
3099
#define ok_pinuse(p) pinuse(p)
3100
3101
#else /* !INSECURE */
3102
#define ok_address(M, a) (1)
3103
#define ok_next(b, n) (1)
3104
#define ok_inuse(p) (1)
3105
#define ok_pinuse(p) (1)
3106
#endif /* !INSECURE */
3107
3108
#if (FOOTERS && !INSECURE)
3109
/* Check if (alleged) mstate m has expected magic field */
3110
#define ok_magic(M) ((M)->magic == mparams.magic)
3111
#else /* (FOOTERS && !INSECURE) */
3112
#define ok_magic(M) (1)
3113
#endif /* (FOOTERS && !INSECURE) */
3114
3115
/* In gcc, use __builtin_expect to minimize impact of checks */
3116
#if !INSECURE
3117
#if defined(__GNUC__) && __GNUC__ >= 3
3118
#define RTCHECK(e) __builtin_expect(e, 1)
3119
#else /* GNUC */
3120
#define RTCHECK(e) (e)
3121
#endif /* GNUC */
3122
#else /* !INSECURE */
3123
#define RTCHECK(e) (1)
3124
#endif /* !INSECURE */
3125
3126
/* macros to set up inuse chunks with or without footers */
3127
3128
#if !FOOTERS
3129
3130
#define mark_inuse_foot(M,p,s)
3131
3132
/* Macros for setting head/foot of non-mmapped chunks */
3133
3134
/* Set cinuse bit and pinuse bit of next chunk */
3135
#define set_inuse(M,p,s)\
3136
((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
3137
((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
3138
3139
/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
3140
#define set_inuse_and_pinuse(M,p,s)\
3141
((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
3142
((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
3143
3144
/* Set size, cinuse and pinuse bit of this chunk */
3145
#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
3146
((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
3147
3148
#else /* FOOTERS */
3149
3150
/* Set foot of inuse chunk to be xor of mstate and seed */
3151
#define mark_inuse_foot(M,p,s)\
3152
(((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
3153
3154
#define get_mstate_for(p)\
3155
((mstate)(((mchunkptr)((char*)(p) +\
3156
(chunksize(p))))->prev_foot ^ mparams.magic))
3157
3158
#define set_inuse(M,p,s)\
3159
((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
3160
(((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
3161
mark_inuse_foot(M,p,s))
3162
3163
#define set_inuse_and_pinuse(M,p,s)\
3164
((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
3165
(((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
3166
mark_inuse_foot(M,p,s))
3167
3168
#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
3169
((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
3170
mark_inuse_foot(M, p, s))
3171
3172
#endif /* !FOOTERS */
3173
3174
/* ---------------------------- setting mparams -------------------------- */
3175
3176
#if LOCK_AT_FORK
3177
static void pre_fork(void) { ACQUIRE_LOCK(&(gm)->mutex); }
3178
static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); }
3179
static void post_fork_child(void) { INITIAL_LOCK(&(gm)->mutex); }
3180
#endif /* LOCK_AT_FORK */
3181
3182
/* Initialize mparams */
3183
static int init_mparams(void) {
3184
#ifdef NEED_GLOBAL_LOCK_INIT
3185
if (malloc_global_mutex_status <= 0)
3186
init_malloc_global_mutex();
3187
#endif
3188
3189
ACQUIRE_MALLOC_GLOBAL_LOCK();
3190
if (mparams.magic == 0) {
3191
size_t magic;
3192
size_t psize;
3193
size_t gsize;
3194
3195
#ifndef WIN32
3196
psize = malloc_getpagesize;
3197
gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);
3198
#else /* WIN32 */
3199
{
3200
SYSTEM_INFO system_info;
3201
GetSystemInfo(&system_info);
3202
psize = system_info.dwPageSize;
3203
gsize = ((DEFAULT_GRANULARITY != 0)?
3204
DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);
3205
}
3206
#endif /* WIN32 */
3207
3208
/* Sanity-check configuration:
3209
size_t must be unsigned and as wide as pointer type.
3210
ints must be at least 4 bytes.
3211
alignment must be at least 8.
3212
Alignment, min chunk size, and page size must all be powers of 2.
3213
*/
3214
if ((sizeof(size_t) != sizeof(char*)) ||
3215
(MAX_SIZE_T < MIN_CHUNK_SIZE) ||
3216
(sizeof(int) < 4) ||
3217
(MALLOC_ALIGNMENT < (size_t)8U) ||
3218
((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||
3219
((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) ||
3220
((gsize & (gsize-SIZE_T_ONE)) != 0) ||
3221
((psize & (psize-SIZE_T_ONE)) != 0))
3222
ABORT;
3223
mparams.granularity = gsize;
3224
mparams.page_size = psize;
3225
mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
3226
mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
3227
#if MORECORE_CONTIGUOUS
3228
mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
3229
#else /* MORECORE_CONTIGUOUS */
3230
mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
3231
#endif /* MORECORE_CONTIGUOUS */
3232
3233
#if !ONLY_MSPACES
3234
/* Set up lock for main malloc area */
3235
gm->mflags = mparams.default_mflags;
3236
(void)INITIAL_LOCK(&gm->mutex);
3237
#endif
3238
#if LOCK_AT_FORK
3239
pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child);
3240
#endif
3241
3242
{
3243
#if USE_DEV_RANDOM
3244
int fd;
3245
unsigned char buf[sizeof(size_t)];
3246
/* Try to use /dev/urandom, else fall back on using time */
3247
if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
3248
read(fd, buf, sizeof(buf)) == sizeof(buf)) {
3249
magic = *((size_t *) buf);
3250
close(fd);
3251
}
3252
else
3253
#endif /* USE_DEV_RANDOM */
3254
#ifdef WIN32
3255
magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);
3256
#elif defined(LACKS_TIME_H) || defined(__EMSCRIPTEN__)
3257
magic = (size_t)&magic ^ (size_t)0x55555555U;
3258
#else
3259
magic = (size_t)(time(0) ^ (size_t)0x55555555U);
3260
#endif
3261
magic |= (size_t)8U; /* ensure nonzero */
3262
magic &= ~(size_t)7U; /* improve chances of fault for bad values */
3263
/* Until memory modes commonly available, use volatile-write */
3264
(*(volatile size_t *)(&(mparams.magic))) = magic;
3265
}
3266
}
3267
3268
RELEASE_MALLOC_GLOBAL_LOCK();
3269
return 1;
3270
}
3271
3272
/* support for mallopt */
3273
static int change_mparam(int param_number, int value) {
3274
size_t val;
3275
ensure_initialization();
3276
val = (value == -1)? MAX_SIZE_T : (size_t)value;
3277
switch(param_number) {
3278
case M_TRIM_THRESHOLD:
3279
mparams.trim_threshold = val;
3280
return 1;
3281
case M_GRANULARITY:
3282
if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
3283
mparams.granularity = val;
3284
return 1;
3285
}
3286
else
3287
return 0;
3288
case M_MMAP_THRESHOLD:
3289
mparams.mmap_threshold = val;
3290
return 1;
3291
default:
3292
return 0;
3293
}
3294
}
3295
3296
#if DEBUG
3297
/* ------------------------- Debugging Support --------------------------- */
3298
3299
/* Check properties of any chunk, whether free, inuse, mmapped etc */
3300
static void do_check_any_chunk(mstate m, mchunkptr p) {
3301
assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
3302
assert(ok_address(m, p));
3303
}
3304
3305
/* Check properties of top chunk */
3306
static void do_check_top_chunk(mstate m, mchunkptr p) {
3307
msegmentptr sp = segment_holding(m, (char*)p);
3308
size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */
3309
assert(sp != 0);
3310
assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
3311
assert(ok_address(m, p));
3312
assert(sz == m->topsize);
3313
assert(sz > 0);
3314
assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
3315
assert(pinuse(p));
3316
assert(!pinuse(chunk_plus_offset(p, sz)));
3317
}
3318
3319
/* Check properties of (inuse) mmapped chunks */
3320
static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
3321
size_t sz = chunksize(p);
3322
size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD);
3323
assert(is_mmapped(p));
3324
assert(use_mmap(m));
3325
assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
3326
assert(ok_address(m, p));
3327
assert(!is_small(sz));
3328
assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
3329
assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
3330
assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
3331
}
3332
3333
/* Check properties of inuse chunks */
3334
static void do_check_inuse_chunk(mstate m, mchunkptr p) {
3335
do_check_any_chunk(m, p);
3336
assert(is_inuse(p));
3337
assert(next_pinuse(p));
3338
/* If not pinuse and not mmapped, previous chunk has OK offset */
3339
assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
3340
if (is_mmapped(p))
3341
do_check_mmapped_chunk(m, p);
3342
}
3343
3344
/* Check properties of free chunks */
3345
static void do_check_free_chunk(mstate m, mchunkptr p) {
3346
size_t sz = chunksize(p);
3347
mchunkptr next = chunk_plus_offset(p, sz);
3348
do_check_any_chunk(m, p);
3349
assert(!is_inuse(p));
3350
assert(!next_pinuse(p));
3351
assert (!is_mmapped(p));
3352
if (p != m->dv && p != m->top) {
3353
if (sz >= MIN_CHUNK_SIZE) {
3354
assert((sz & CHUNK_ALIGN_MASK) == 0);
3355
assert(is_aligned(chunk2mem(p)));
3356
assert(next->prev_foot == sz);
3357
assert(pinuse(p));
3358
assert (next == m->top || is_inuse(next));
3359
assert(p->fd->bk == p);
3360
assert(p->bk->fd == p);
3361
}
3362
else /* markers are always of size SIZE_T_SIZE */
3363
assert(sz == SIZE_T_SIZE);
3364
}
3365
}
3366
3367
/* Check properties of malloced chunks at the point they are malloced */
3368
static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
3369
if (mem != 0) {
3370
mchunkptr p = mem2chunk(mem);
3371
size_t sz = p->head & ~INUSE_BITS;
3372
do_check_inuse_chunk(m, p);
3373
assert((sz & CHUNK_ALIGN_MASK) == 0);
3374
assert(sz >= MIN_CHUNK_SIZE);
3375
assert(sz >= s);
3376
/* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
3377
assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
3378
}
3379
}
3380
3381
/* Check a tree and its subtrees. */
3382
static void do_check_tree(mstate m, tchunkptr t) {
3383
tchunkptr head = 0;
3384
tchunkptr u = t;
3385
bindex_t tindex = t->index;
3386
size_t tsize = chunksize(t);
3387
bindex_t idx;
3388
compute_tree_index(tsize, idx);
3389
assert(tindex == idx);
3390
assert(tsize >= MIN_LARGE_SIZE);
3391
assert(tsize >= minsize_for_tree_index(idx));
3392
assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
3393
3394
do { /* traverse through chain of same-sized nodes */
3395
do_check_any_chunk(m, ((mchunkptr)u));
3396
assert(u->index == tindex);
3397
assert(chunksize(u) == tsize);
3398
assert(!is_inuse(u));
3399
assert(!next_pinuse(u));
3400
assert(u->fd->bk == u);
3401
assert(u->bk->fd == u);
3402
if (u->parent == 0) {
3403
assert(u->child[0] == 0);
3404
assert(u->child[1] == 0);
3405
}
3406
else {
3407
assert(head == 0); /* only one node on chain has parent */
3408
head = u;
3409
assert(u->parent != u);
3410
assert (u->parent->child[0] == u ||
3411
u->parent->child[1] == u ||
3412
*((tbinptr*)(u->parent)) == u);
3413
if (u->child[0] != 0) {
3414
assert(u->child[0]->parent == u);
3415
assert(u->child[0] != u);
3416
do_check_tree(m, u->child[0]);
3417
}
3418
if (u->child[1] != 0) {
3419
assert(u->child[1]->parent == u);
3420
assert(u->child[1] != u);
3421
do_check_tree(m, u->child[1]);
3422
}
3423
if (u->child[0] != 0 && u->child[1] != 0) {
3424
assert(chunksize(u->child[0]) < chunksize(u->child[1]));
3425
}
3426
}
3427
u = u->fd;
3428
} while (u != t);
3429
assert(head != 0);
3430
}
3431
3432
/* Check all the chunks in a treebin. */
3433
static void do_check_treebin(mstate m, bindex_t i) {
3434
tbinptr* tb = treebin_at(m, i);
3435
tchunkptr t = *tb;
3436
int empty = (m->treemap & (1U << i)) == 0;
3437
if (t == 0)
3438
assert(empty);
3439
if (!empty)
3440
do_check_tree(m, t);
3441
}
3442
3443
/* Check all the chunks in a smallbin. */
3444
static void do_check_smallbin(mstate m, bindex_t i) {
3445
sbinptr b = smallbin_at(m, i);
3446
mchunkptr p = b->bk;
3447
unsigned int empty = (m->smallmap & (1U << i)) == 0;
3448
if (p == b)
3449
assert(empty);
3450
if (!empty) {
3451
for (; p != b; p = p->bk) {
3452
size_t size = chunksize(p);
3453
mchunkptr q;
3454
/* each chunk claims to be free */
3455
do_check_free_chunk(m, p);
3456
/* chunk belongs in bin */
3457
assert(small_index(size) == i);
3458
assert(p->bk == b || chunksize(p->bk) == chunksize(p));
3459
/* chunk is followed by an inuse chunk */
3460
q = next_chunk(p);
3461
if (q->head != FENCEPOST_HEAD)
3462
do_check_inuse_chunk(m, q);
3463
}
3464
}
3465
}
3466
3467
/* Find x in a bin. Used in other check functions. */
3468
static int bin_find(mstate m, mchunkptr x) {
3469
size_t size = chunksize(x);
3470
if (is_small(size)) {
3471
bindex_t sidx = small_index(size);
3472
sbinptr b = smallbin_at(m, sidx);
3473
if (smallmap_is_marked(m, sidx)) {
3474
mchunkptr p = b;
3475
do {
3476
if (p == x)
3477
return 1;
3478
} while ((p = p->fd) != b);
3479
}
3480
}
3481
else {
3482
bindex_t tidx;
3483
compute_tree_index(size, tidx);
3484
if (treemap_is_marked(m, tidx)) {
3485
tchunkptr t = *treebin_at(m, tidx);
3486
size_t sizebits = size << leftshift_for_tree_index(tidx);
3487
while (t != 0 && chunksize(t) != size) {
3488
t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
3489
sizebits <<= 1;
3490
}
3491
if (t != 0) {
3492
tchunkptr u = t;
3493
do {
3494
if (u == (tchunkptr)x)
3495
return 1;
3496
} while ((u = u->fd) != t);
3497
}
3498
}
3499
}
3500
return 0;
3501
}
3502
3503
/* Traverse each chunk and check it; return total */
3504
static size_t traverse_and_check(mstate m) {
3505
size_t sum = 0;
3506
if (is_initialized(m)) {
3507
msegmentptr s = &m->seg;
3508
sum += m->topsize + TOP_FOOT_SIZE;
3509
while (s != 0) {
3510
mchunkptr q = align_as_chunk(s->base);
3511
mchunkptr lastq = 0;
3512
assert(pinuse(q));
3513
while (segment_holds(s, q) &&
3514
q != m->top && q->head != FENCEPOST_HEAD) {
3515
sum += chunksize(q);
3516
if (is_inuse(q)) {
3517
assert(!bin_find(m, q));
3518
do_check_inuse_chunk(m, q);
3519
}
3520
else {
3521
assert(q == m->dv || bin_find(m, q));
3522
assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */
3523
do_check_free_chunk(m, q);
3524
}
3525
lastq = q;
3526
q = next_chunk(q);
3527
}
3528
s = s->next;
3529
}
3530
}
3531
return sum;
3532
}
3533
3534
3535
/* Check all properties of malloc_state. */
3536
static void do_check_malloc_state(mstate m) {
3537
bindex_t i;
3538
size_t total;
3539
/* check bins */
3540
for (i = 0; i < NSMALLBINS; ++i)
3541
do_check_smallbin(m, i);
3542
for (i = 0; i < NTREEBINS; ++i)
3543
do_check_treebin(m, i);
3544
3545
if (m->dvsize != 0) { /* check dv chunk */
3546
do_check_any_chunk(m, m->dv);
3547
assert(m->dvsize == chunksize(m->dv));
3548
assert(m->dvsize >= MIN_CHUNK_SIZE);
3549
assert(bin_find(m, m->dv) == 0);
3550
}
3551
3552
if (m->top != 0) { /* check top chunk */
3553
do_check_top_chunk(m, m->top);
3554
/*assert(m->topsize == chunksize(m->top)); redundant */
3555
assert(m->topsize > 0);
3556
assert(bin_find(m, m->top) == 0);
3557
}
3558
3559
total = traverse_and_check(m);
3560
assert(total <= m->footprint);
3561
assert(m->footprint <= m->max_footprint);
3562
}
3563
#endif /* DEBUG */
3564
3565
/* ----------------------------- statistics ------------------------------ */
3566
3567
#if !NO_MALLINFO
3568
static struct mallinfo internal_mallinfo(mstate m) {
3569
struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3570
ensure_initialization();
3571
if (!PREACTION(m)) {
3572
check_malloc_state(m);
3573
if (is_initialized(m)) {
3574
size_t nfree = SIZE_T_ONE; /* top always free */
3575
size_t mfree = m->topsize + TOP_FOOT_SIZE;
3576
size_t sum = mfree;
3577
msegmentptr s = &m->seg;
3578
while (s != 0) {
3579
mchunkptr q = align_as_chunk(s->base);
3580
while (segment_holds(s, q) &&
3581
q != m->top && q->head != FENCEPOST_HEAD) {
3582
size_t sz = chunksize(q);
3583
sum += sz;
3584
if (!is_inuse(q)) {
3585
mfree += sz;
3586
++nfree;
3587
}
3588
q = next_chunk(q);
3589
}
3590
s = s->next;
3591
}
3592
3593
nm.arena = sum;
3594
nm.ordblks = nfree;
3595
nm.hblkhd = m->footprint - sum;
3596
nm.usmblks = m->max_footprint;
3597
nm.uordblks = m->footprint - mfree;
3598
nm.fordblks = mfree;
3599
nm.keepcost = m->topsize;
3600
}
3601
3602
POSTACTION(m);
3603
}
3604
return nm;
3605
}
3606
#endif /* !NO_MALLINFO */
3607
3608
#if !NO_MALLOC_STATS
3609
static void internal_malloc_stats(mstate m) {
3610
ensure_initialization();
3611
if (!PREACTION(m)) {
3612
size_t maxfp = 0;
3613
size_t fp = 0;
3614
size_t used = 0;
3615
check_malloc_state(m);
3616
if (is_initialized(m)) {
3617
msegmentptr s = &m->seg;
3618
maxfp = m->max_footprint;
3619
fp = m->footprint;
3620
used = fp - (m->topsize + TOP_FOOT_SIZE);
3621
3622
while (s != 0) {
3623
mchunkptr q = align_as_chunk(s->base);
3624
while (segment_holds(s, q) &&
3625
q != m->top && q->head != FENCEPOST_HEAD) {
3626
if (!is_inuse(q))
3627
used -= chunksize(q);
3628
q = next_chunk(q);
3629
}
3630
s = s->next;
3631
}
3632
}
3633
POSTACTION(m); /* drop lock */
3634
fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
3635
fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp));
3636
fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used));
3637
}
3638
}
3639
#endif /* NO_MALLOC_STATS */
3640
3641
/* ----------------------- Operations on smallbins ----------------------- */
3642
3643
/*
3644
Various forms of linking and unlinking are defined as macros. Even
3645
the ones for trees, which are very long but have very short typical
3646
paths. This is ugly but reduces reliance on inlining support of
3647
compilers.
3648
*/
3649
3650
/* Link a free chunk into a smallbin */
3651
#define insert_small_chunk(M, P, S) {\
3652
bindex_t I = small_index(S);\
3653
mchunkptr B = smallbin_at(M, I);\
3654
mchunkptr F = B;\
3655
assert(S >= MIN_CHUNK_SIZE);\
3656
if (!smallmap_is_marked(M, I))\
3657
mark_smallmap(M, I);\
3658
else if (RTCHECK(ok_address(M, B->fd)))\
3659
F = B->fd;\
3660
else {\
3661
CORRUPTION_ERROR_ACTION(M);\
3662
}\
3663
B->fd = P;\
3664
F->bk = P;\
3665
P->fd = F;\
3666
P->bk = B;\
3667
}
3668
3669
/* Unlink a chunk from a smallbin */
3670
#define unlink_small_chunk(M, P, S) {\
3671
mchunkptr F = P->fd;\
3672
mchunkptr B = P->bk;\
3673
bindex_t I = small_index(S);\
3674
assert(P != B);\
3675
assert(P != F);\
3676
assert(chunksize(P) == small_index2size(I));\
3677
if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \
3678
if (B == F) {\
3679
clear_smallmap(M, I);\
3680
}\
3681
else if (RTCHECK(B == smallbin_at(M,I) ||\
3682
(ok_address(M, B) && B->fd == P))) {\
3683
F->bk = B;\
3684
B->fd = F;\
3685
}\
3686
else {\
3687
CORRUPTION_ERROR_ACTION(M);\
3688
}\
3689
}\
3690
else {\
3691
CORRUPTION_ERROR_ACTION(M);\
3692
}\
3693
}
3694
3695
/* Unlink the first chunk from a smallbin */
3696
#define unlink_first_small_chunk(M, B, P, I) {\
3697
mchunkptr F = P->fd;\
3698
assert(P != B);\
3699
assert(P != F);\
3700
assert(chunksize(P) == small_index2size(I));\
3701
if (B == F) {\
3702
clear_smallmap(M, I);\
3703
}\
3704
else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\
3705
F->bk = B;\
3706
B->fd = F;\
3707
}\
3708
else {\
3709
CORRUPTION_ERROR_ACTION(M);\
3710
}\
3711
}
3712
3713
/* Replace dv node, binning the old one */
3714
/* Used only when dvsize known to be small */
3715
#define replace_dv(M, P, S) {\
3716
size_t DVS = M->dvsize;\
3717
assert(is_small(DVS));\
3718
if (DVS != 0) {\
3719
mchunkptr DV = M->dv;\
3720
insert_small_chunk(M, DV, DVS);\
3721
}\
3722
M->dvsize = S;\
3723
M->dv = P;\
3724
}
3725
3726
/* ------------------------- Operations on trees ------------------------- */
3727
3728
/* Insert chunk into tree */
3729
#define insert_large_chunk(M, X, S) {\
3730
tbinptr* H;\
3731
bindex_t I;\
3732
compute_tree_index(S, I);\
3733
H = treebin_at(M, I);\
3734
X->index = I;\
3735
X->child[0] = X->child[1] = 0;\
3736
if (!treemap_is_marked(M, I)) {\
3737
mark_treemap(M, I);\
3738
*H = X;\
3739
X->parent = (tchunkptr)H;\
3740
X->fd = X->bk = X;\
3741
}\
3742
else {\
3743
tchunkptr T = *H;\
3744
size_t K = S << leftshift_for_tree_index(I);\
3745
for (;;) {\
3746
if (chunksize(T) != S) {\
3747
tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
3748
K <<= 1;\
3749
if (*C != 0)\
3750
T = *C;\
3751
else if (RTCHECK(ok_address(M, C))) {\
3752
*C = X;\
3753
X->parent = T;\
3754
X->fd = X->bk = X;\
3755
break;\
3756
}\
3757
else {\
3758
CORRUPTION_ERROR_ACTION(M);\
3759
break;\
3760
}\
3761
}\
3762
else {\
3763
tchunkptr F = T->fd;\
3764
if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
3765
T->fd = F->bk = X;\
3766
X->fd = F;\
3767
X->bk = T;\
3768
X->parent = 0;\
3769
break;\
3770
}\
3771
else {\
3772
CORRUPTION_ERROR_ACTION(M);\
3773
break;\
3774
}\
3775
}\
3776
}\
3777
}\
3778
}
3779
3780
/*
3781
Unlink steps:
3782
3783
1. If x is a chained node, unlink it from its same-sized fd/bk links
3784
and choose its bk node as its replacement.
3785
2. If x was the last node of its size, but not a leaf node, it must
3786
be replaced with a leaf node (not merely one with an open left or
3787
right), to make sure that lefts and rights of descendents
3788
correspond properly to bit masks. We use the rightmost descendent
3789
of x. We could use any other leaf, but this is easy to locate and
3790
tends to counteract removal of leftmosts elsewhere, and so keeps
3791
paths shorter than minimally guaranteed. This doesn't loop much
3792
because on average a node in a tree is near the bottom.
3793
3. If x is the base of a chain (i.e., has parent links) relink
3794
x's parent and children to x's replacement (or null if none).
3795
*/
3796
3797
#define unlink_large_chunk(M, X) { \
3798
tchunkptr XP = X->parent; \
3799
tchunkptr R; \
3800
if (X->bk != X) { \
3801
tchunkptr F = X->fd; \
3802
R = X->bk; \
3803
if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) { \
3804
F->bk = R; \
3805
R->fd = F; \
3806
} \
3807
else { \
3808
CORRUPTION_ERROR_ACTION(M); \
3809
} \
3810
} \
3811
else { \
3812
tchunkptr* RP; \
3813
if (((R = *(RP = &(X->child[1]))) != 0) || \
3814
((R = *(RP = &(X->child[0]))) != 0)) { \
3815
tchunkptr* CP; \
3816
while ((*(CP = &(R->child[1])) != 0) || \
3817
(*(CP = &(R->child[0])) != 0)) { \
3818
R = *(RP = CP); \
3819
} \
3820
if (RTCHECK(ok_address(M, RP))) \
3821
*RP = 0; \
3822
else { \
3823
CORRUPTION_ERROR_ACTION(M); \
3824
} \
3825
} \
3826
} \
3827
if (XP != 0) { \
3828
tbinptr* H = treebin_at(M, X->index); \
3829
if (X == *H) { \
3830
if ((*H = R) == 0) \
3831
clear_treemap(M, X->index); \
3832
} \
3833
else if (RTCHECK(ok_address(M, XP))) { \
3834
if (XP->child[0] == X) \
3835
XP->child[0] = R; \
3836
else \
3837
XP->child[1] = R; \
3838
} \
3839
else \
3840
CORRUPTION_ERROR_ACTION(M); \
3841
if (R != 0) { \
3842
if (RTCHECK(ok_address(M, R))) { \
3843
tchunkptr C0, C1; \
3844
R->parent = XP; \
3845
if ((C0 = X->child[0]) != 0) { \
3846
if (RTCHECK(ok_address(M, C0))) { \
3847
R->child[0] = C0; \
3848
C0->parent = R; \
3849
} \
3850
else \
3851
CORRUPTION_ERROR_ACTION(M); \
3852
} \
3853
if ((C1 = X->child[1]) != 0) { \
3854
if (RTCHECK(ok_address(M, C1))) { \
3855
R->child[1] = C1; \
3856
C1->parent = R; \
3857
} \
3858
else \
3859
CORRUPTION_ERROR_ACTION(M); \
3860
} \
3861
} \
3862
else \
3863
CORRUPTION_ERROR_ACTION(M); \
3864
} \
3865
} \
3866
}
3867
3868
/* Relays to large vs small bin operations */
3869
3870
#define insert_chunk(M, P, S) \
3871
if (is_small(S)) insert_small_chunk(M, P, S) \
3872
else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
3873
3874
#define unlink_chunk(M, P, S) \
3875
if (is_small(S)) unlink_small_chunk(M, P, S) \
3876
else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
3877
3878
3879
/* Relays to internal calls to malloc/free from realloc, memalign etc */
3880
3881
#if ONLY_MSPACES
3882
#define internal_malloc(m, b) mspace_malloc(m, b)
3883
#define internal_free(m, mem) mspace_free(m,mem);
3884
#else /* ONLY_MSPACES */
3885
#if MSPACES
3886
#define internal_malloc(m, b)\
3887
((m == gm)? dlmalloc(b) : mspace_malloc(m, b))
3888
#define internal_free(m, mem)\
3889
if (m == gm) dlfree(mem); else mspace_free(m,mem);
3890
#else /* MSPACES */
3891
#define internal_malloc(m, b) dlmalloc(b)
3892
#define internal_free(m, mem) dlfree(mem)
3893
#endif /* MSPACES */
3894
#endif /* ONLY_MSPACES */
3895
3896
/* ----------------------- Direct-mmapping chunks ----------------------- */
3897
3898
/*
3899
Directly mmapped chunks are set up with an offset to the start of
3900
the mmapped region stored in the prev_foot field of the chunk. This
3901
allows reconstruction of the required argument to MUNMAP when freed,
3902
and also allows adjustment of the returned chunk to meet alignment
3903
requirements (especially in memalign).
3904
*/
3905
3906
/* Malloc using mmap */
3907
static void* mmap_alloc(mstate m, size_t nb) {
3908
size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
3909
if (m->footprint_limit != 0) {
3910
size_t fp = m->footprint + mmsize;
3911
if (fp <= m->footprint || fp > m->footprint_limit)
3912
return 0;
3913
}
3914
if (mmsize > nb) { /* Check for wrap around 0 */
3915
char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));
3916
if (mm != CMFAIL) {
3917
size_t offset = align_offset(chunk2mem(mm));
3918
size_t psize = mmsize - offset - MMAP_FOOT_PAD;
3919
mchunkptr p = (mchunkptr)(mm + offset);
3920
p->prev_foot = offset;
3921
p->head = psize;
3922
mark_inuse_foot(m, p, psize);
3923
chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
3924
chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
3925
3926
if (m->least_addr == 0 || mm < m->least_addr)
3927
m->least_addr = mm;
3928
if ((m->footprint += mmsize) > m->max_footprint)
3929
m->max_footprint = m->footprint;
3930
assert(is_aligned(chunk2mem(p)));
3931
check_mmapped_chunk(m, p);
3932
return chunk2mem(p);
3933
}
3934
}
3935
return 0;
3936
}
3937
3938
/* Realloc using mmap */
3939
static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
3940
size_t oldsize = chunksize(oldp);
3941
(void)flags; /* placate people compiling -Wunused */
3942
if (is_small(nb)) /* Can't shrink mmap regions below small size */
3943
return 0;
3944
/* Keep old chunk if big enough but not too big */
3945
if (oldsize >= nb + SIZE_T_SIZE &&
3946
(oldsize - nb) <= (mparams.granularity << 1))
3947
return oldp;
3948
else {
3949
size_t offset = oldp->prev_foot;
3950
size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
3951
size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
3952
char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
3953
oldmmsize, newmmsize, flags);
3954
if (cp != CMFAIL) {
3955
mchunkptr newp = (mchunkptr)(cp + offset);
3956
size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
3957
newp->head = psize;
3958
mark_inuse_foot(m, newp, psize);
3959
chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
3960
chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
3961
3962
if (cp < m->least_addr)
3963
m->least_addr = cp;
3964
if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
3965
m->max_footprint = m->footprint;
3966
check_mmapped_chunk(m, newp);
3967
return newp;
3968
}
3969
}
3970
return 0;
3971
}
3972
3973
3974
/* -------------------------- mspace management -------------------------- */
3975
3976
/* Initialize top chunk and its size */
3977
static void init_top(mstate m, mchunkptr p, size_t psize) {
3978
/* Ensure alignment */
3979
size_t offset = align_offset(chunk2mem(p));
3980
p = (mchunkptr)((char*)p + offset);
3981
psize -= offset;
3982
3983
m->top = p;
3984
m->topsize = psize;
3985
p->head = psize | PINUSE_BIT;
3986
/* set size of fake trailing chunk holding overhead space only once */
3987
chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
3988
m->trim_check = mparams.trim_threshold; /* reset on each update */
3989
}
3990
3991
/* Initialize bins for a new mstate that is otherwise zeroed out */
3992
static void init_bins(mstate m) {
3993
/* Establish circular links for smallbins */
3994
bindex_t i;
3995
for (i = 0; i < NSMALLBINS; ++i) {
3996
sbinptr bin = smallbin_at(m,i);
3997
bin->fd = bin->bk = bin;
3998
}
3999
}
4000
4001
#if PROCEED_ON_ERROR
4002
4003
/* default corruption action */
4004
static void reset_on_error(mstate m) {
4005
int i;
4006
++malloc_corruption_error_count;
4007
/* Reinitialize fields to forget about all memory */
4008
m->smallmap = m->treemap = 0;
4009
m->dvsize = m->topsize = 0;
4010
m->seg.base = 0;
4011
m->seg.size = 0;
4012
m->seg.next = 0;
4013
m->top = m->dv = 0;
4014
for (i = 0; i < NTREEBINS; ++i)
4015
*treebin_at(m, i) = 0;
4016
init_bins(m);
4017
}
4018
#endif /* PROCEED_ON_ERROR */
4019
4020
/* Allocate chunk and prepend remainder with chunk in successor base. */
4021
static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
4022
size_t nb) {
4023
mchunkptr p = align_as_chunk(newbase);
4024
mchunkptr oldfirst = align_as_chunk(oldbase);
4025
size_t psize = (char*)oldfirst - (char*)p;
4026
mchunkptr q = chunk_plus_offset(p, nb);
4027
size_t qsize = psize - nb;
4028
set_size_and_pinuse_of_inuse_chunk(m, p, nb);
4029
4030
assert((char*)oldfirst > (char*)q);
4031
assert(pinuse(oldfirst));
4032
assert(qsize >= MIN_CHUNK_SIZE);
4033
4034
/* consolidate remainder with first chunk of old base */
4035
if (oldfirst == m->top) {
4036
size_t tsize = m->topsize += qsize;
4037
m->top = q;
4038
q->head = tsize | PINUSE_BIT;
4039
check_top_chunk(m, q);
4040
}
4041
else if (oldfirst == m->dv) {
4042
size_t dsize = m->dvsize += qsize;
4043
m->dv = q;
4044
set_size_and_pinuse_of_free_chunk(q, dsize);
4045
}
4046
else {
4047
if (!is_inuse(oldfirst)) {
4048
size_t nsize = chunksize(oldfirst);
4049
unlink_chunk(m, oldfirst, nsize);
4050
oldfirst = chunk_plus_offset(oldfirst, nsize);
4051
qsize += nsize;
4052
}
4053
set_free_with_pinuse(q, qsize, oldfirst);
4054
insert_chunk(m, q, qsize);
4055
check_free_chunk(m, q);
4056
}
4057
4058
check_malloced_chunk(m, chunk2mem(p), nb);
4059
return chunk2mem(p);
4060
}
4061
4062
/* Add a segment to hold a new noncontiguous region */
4063
static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
4064
/* Determine locations and sizes of segment, fenceposts, old top */
4065
char* old_top = (char*)m->top;
4066
msegmentptr oldsp = segment_holding(m, old_top);
4067
char* old_end = oldsp->base + oldsp->size;
4068
size_t ssize = pad_request(sizeof(struct malloc_segment));
4069
char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
4070
size_t offset = align_offset(chunk2mem(rawsp));
4071
char* asp = rawsp + offset;
4072
char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
4073
mchunkptr sp = (mchunkptr)csp;
4074
msegmentptr ss = (msegmentptr)(chunk2mem(sp));
4075
mchunkptr tnext = chunk_plus_offset(sp, ssize);
4076
mchunkptr p = tnext;
4077
int nfences = 0;
4078
4079
/* reset top to new space */
4080
init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
4081
4082
/* Set up segment record */
4083
assert(is_aligned(ss));
4084
set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
4085
*ss = m->seg; /* Push current record */
4086
m->seg.base = tbase;
4087
m->seg.size = tsize;
4088
m->seg.sflags = mmapped;
4089
m->seg.next = ss;
4090
4091
/* Insert trailing fenceposts */
4092
for (;;) {
4093
mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
4094
p->head = FENCEPOST_HEAD;
4095
++nfences;
4096
if ((char*)(&(nextp->head)) < old_end)
4097
p = nextp;
4098
else
4099
break;
4100
}
4101
assert(nfences >= 2);
4102
4103
/* Insert the rest of old top into a bin as an ordinary free chunk */
4104
if (csp != old_top) {
4105
mchunkptr q = (mchunkptr)old_top;
4106
size_t psize = csp - old_top;
4107
mchunkptr tn = chunk_plus_offset(q, psize);
4108
set_free_with_pinuse(q, psize, tn);
4109
insert_chunk(m, q, psize);
4110
}
4111
4112
check_top_chunk(m, m->top);
4113
}
4114
4115
/* -------------------------- System allocation -------------------------- */
4116
4117
/* Get memory from system using MORECORE or MMAP */
4118
static void* sys_alloc(mstate m, size_t nb) {
4119
char* tbase = CMFAIL;
4120
size_t tsize = 0;
4121
flag_t mmap_flag = 0;
4122
size_t asize; /* allocation size */
4123
4124
ensure_initialization();
4125
4126
/* Directly map large chunks, but only if already initialized */
4127
if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) {
4128
void* mem = mmap_alloc(m, nb);
4129
if (mem != 0)
4130
return mem;
4131
}
4132
4133
asize = granularity_align(nb + SYS_ALLOC_PADDING);
4134
if (asize <= nb)
4135
return 0; /* wraparound */
4136
if (m->footprint_limit != 0) {
4137
size_t fp = m->footprint + asize;
4138
if (fp <= m->footprint || fp > m->footprint_limit)
4139
return 0;
4140
}
4141
4142
/*
4143
Try getting memory in any of three ways (in most-preferred to
4144
least-preferred order):
4145
1. A call to MORECORE that can normally contiguously extend memory.
4146
(disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
4147
or main space is mmapped or a previous contiguous call failed)
4148
2. A call to MMAP new space (disabled if not HAVE_MMAP).
4149
Note that under the default settings, if MORECORE is unable to
4150
fulfill a request, and HAVE_MMAP is true, then mmap is
4151
used as a noncontiguous system allocator. This is a useful backup
4152
strategy for systems with holes in address spaces -- in this case
4153
sbrk cannot contiguously expand the heap, but mmap may be able to
4154
find space.
4155
3. A call to MORECORE that cannot usually contiguously extend memory.
4156
(disabled if not HAVE_MORECORE)
4157
4158
In all cases, we need to request enough bytes from system to ensure
4159
we can malloc nb bytes upon success, so pad with enough space for
4160
top_foot, plus alignment-pad to make sure we don't lose bytes if
4161
not on boundary, and round this up to a granularity unit.
4162
*/
4163
4164
if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
4165
char* br = CMFAIL;
4166
size_t ssize = asize; /* sbrk call size */
4167
msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
4168
ACQUIRE_MALLOC_GLOBAL_LOCK();
4169
4170
if (ss == 0) { /* First time through or recovery */
4171
char* base = (char*)CALL_MORECORE(0);
4172
if (base != CMFAIL) {
4173
size_t fp;
4174
/* Adjust to end on a page boundary */
4175
if (!is_page_aligned(base))
4176
ssize += (page_align((size_t)base) - (size_t)base);
4177
fp = m->footprint + ssize; /* recheck limits */
4178
if (ssize > nb &&
4179
(UNSIGNED_MORECORE || ssize < HALF_MAX_SIZE_T) &&
4180
(m->footprint_limit == 0 ||
4181
(fp > m->footprint && fp <= m->footprint_limit)) &&
4182
(br = (char*)(CALL_MORECORE(ssize))) == base) {
4183
tbase = base;
4184
tsize = ssize;
4185
}
4186
}
4187
}
4188
else {
4189
/* Subtract out existing available top space from MORECORE request. */
4190
ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);
4191
/* Use mem here only if it did continuously extend old space */
4192
if ((UNSIGNED_MORECORE || ssize < HALF_MAX_SIZE_T) &&
4193
(br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) {
4194
tbase = br;
4195
tsize = ssize;
4196
}
4197
}
4198
4199
if (tbase == CMFAIL) { /* Cope with partial failure */
4200
if (br != CMFAIL) { /* Try to use/extend the space we did get */
4201
if ((UNSIGNED_MORECORE || ssize < HALF_MAX_SIZE_T) &&
4202
ssize < nb + SYS_ALLOC_PADDING) {
4203
size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize);
4204
if (UNSIGNED_MORECORE || esize < HALF_MAX_SIZE_T) {
4205
char* end = (char*)CALL_MORECORE(esize);
4206
if (end != CMFAIL)
4207
ssize += esize;
4208
else { /* Can't use; try to release */
4209
if (!UNSIGNED_MORECORE) {
4210
(void) CALL_MORECORE(-ssize);
4211
}
4212
br = CMFAIL;
4213
}
4214
}
4215
}
4216
}
4217
if (br != CMFAIL) { /* Use the space we did get */
4218
tbase = br;
4219
tsize = ssize;
4220
}
4221
else
4222
disable_contiguous(m); /* Don't try contiguous path in the future */
4223
}
4224
4225
RELEASE_MALLOC_GLOBAL_LOCK();
4226
}
4227
4228
if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */
4229
char* mp = (char*)(CALL_MMAP(asize));
4230
if (mp != CMFAIL) {
4231
tbase = mp;
4232
tsize = asize;
4233
mmap_flag = USE_MMAP_BIT;
4234
}
4235
}
4236
4237
if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
4238
if (UNSIGNED_MORECORE || asize < HALF_MAX_SIZE_T) {
4239
char* br = CMFAIL;
4240
char* end = CMFAIL;
4241
ACQUIRE_MALLOC_GLOBAL_LOCK();
4242
br = (char*)(CALL_MORECORE(asize));
4243
end = (char*)(CALL_MORECORE(0));
4244
RELEASE_MALLOC_GLOBAL_LOCK();
4245
if (br != CMFAIL && end != CMFAIL && br < end) {
4246
size_t ssize = end - br;
4247
if (ssize > nb + TOP_FOOT_SIZE) {
4248
tbase = br;
4249
tsize = ssize;
4250
}
4251
}
4252
}
4253
}
4254
4255
if (tbase != CMFAIL) {
4256
4257
if ((m->footprint += tsize) > m->max_footprint)
4258
m->max_footprint = m->footprint;
4259
4260
if (!is_initialized(m)) { /* first-time initialization */
4261
if (m->least_addr == 0 || tbase < m->least_addr)
4262
m->least_addr = tbase;
4263
m->seg.base = tbase;
4264
m->seg.size = tsize;
4265
m->seg.sflags = mmap_flag;
4266
m->magic = mparams.magic;
4267
m->release_checks = MAX_RELEASE_CHECK_RATE;
4268
init_bins(m);
4269
#if !ONLY_MSPACES
4270
if (is_global(m))
4271
init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
4272
else
4273
#endif
4274
{
4275
/* Offset top by embedded malloc_state */
4276
mchunkptr mn = next_chunk(mem2chunk(m));
4277
init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
4278
}
4279
}
4280
4281
else {
4282
/* Try to merge with an existing segment */
4283
msegmentptr sp = &m->seg;
4284
/* Only consider most recent segment if traversal suppressed */
4285
while (sp != 0 && tbase != sp->base + sp->size)
4286
sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
4287
if (sp != 0 &&
4288
!is_extern_segment(sp) &&
4289
(sp->sflags & USE_MMAP_BIT) == mmap_flag &&
4290
segment_holds(sp, m->top)) { /* append */
4291
sp->size += tsize;
4292
init_top(m, m->top, m->topsize + tsize);
4293
}
4294
else {
4295
if (tbase < m->least_addr)
4296
m->least_addr = tbase;
4297
sp = &m->seg;
4298
while (sp != 0 && sp->base != tbase + tsize)
4299
sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
4300
if (sp != 0 &&
4301
!is_extern_segment(sp) &&
4302
(sp->sflags & USE_MMAP_BIT) == mmap_flag) {
4303
char* oldbase = sp->base;
4304
sp->base = tbase;
4305
sp->size += tsize;
4306
return prepend_alloc(m, tbase, oldbase, nb);
4307
}
4308
else
4309
add_segment(m, tbase, tsize, mmap_flag);
4310
}
4311
}
4312
4313
if (nb < m->topsize) { /* Allocate from new or extended top space */
4314
size_t rsize = m->topsize -= nb;
4315
mchunkptr p = m->top;
4316
mchunkptr r = m->top = chunk_plus_offset(p, nb);
4317
r->head = rsize | PINUSE_BIT;
4318
set_size_and_pinuse_of_inuse_chunk(m, p, nb);
4319
check_top_chunk(m, m->top);
4320
check_malloced_chunk(m, chunk2mem(p), nb);
4321
return chunk2mem(p);
4322
}
4323
}
4324
4325
MALLOC_FAILURE_ACTION;
4326
return 0;
4327
}
4328
4329
/* ----------------------- system deallocation -------------------------- */
4330
4331
/* Unmap and unlink any mmapped segments that don't contain used chunks */
4332
static size_t release_unused_segments(mstate m) {
4333
size_t released = 0;
4334
int nsegs = 0;
4335
msegmentptr pred = &m->seg;
4336
msegmentptr sp = pred->next;
4337
while (sp != 0) {
4338
char* base = sp->base;
4339
size_t size = sp->size;
4340
msegmentptr next = sp->next;
4341
++nsegs;
4342
if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
4343
mchunkptr p = align_as_chunk(base);
4344
size_t psize = chunksize(p);
4345
/* Can unmap if first chunk holds entire segment and not pinned */
4346
if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
4347
tchunkptr tp = (tchunkptr)p;
4348
assert(segment_holds(sp, (char*)sp));
4349
if (p == m->dv) {
4350
m->dv = 0;
4351
m->dvsize = 0;
4352
}
4353
else {
4354
unlink_large_chunk(m, tp);
4355
}
4356
if (CALL_MUNMAP(base, size) == 0) {
4357
released += size;
4358
m->footprint -= size;
4359
/* unlink obsoleted record */
4360
sp = pred;
4361
sp->next = next;
4362
}
4363
else { /* back out if cannot unmap */
4364
insert_large_chunk(m, tp, psize);
4365
}
4366
}
4367
}
4368
if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */
4369
break;
4370
pred = sp;
4371
sp = next;
4372
}
4373
/* Reset check counter */
4374
m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)?
4375
(size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE);
4376
return released;
4377
}
4378
4379
static int sys_trim(mstate m, size_t pad) {
4380
size_t released = 0;
4381
ensure_initialization();
4382
if (pad < MAX_REQUEST && is_initialized(m)) {
4383
pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
4384
4385
if (m->topsize > pad) {
4386
/* Shrink top space in granularity-size units, keeping at least one */
4387
size_t unit = mparams.granularity;
4388
size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
4389
SIZE_T_ONE) * unit;
4390
msegmentptr sp = segment_holding(m, (char*)m->top);
4391
4392
if (!is_extern_segment(sp)) {
4393
if (is_mmapped_segment(sp)) {
4394
if (HAVE_MMAP &&
4395
sp->size >= extra &&
4396
!has_segment_link(m, sp)) { /* can't shrink if pinned */
4397
size_t newsize = sp->size - extra;
4398
(void)newsize; /* placate people compiling -Wunused-variable */
4399
/* Prefer mremap, fall back to munmap */
4400
if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
4401
(CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
4402
released = extra;
4403
}
4404
}
4405
}
4406
else if (HAVE_MORECORE) {
4407
#ifndef MORECORE_CANNOT_TRIM
4408
if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
4409
extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
4410
ACQUIRE_MALLOC_GLOBAL_LOCK();
4411
{
4412
/* Make sure end of memory is where we last set it. */
4413
char* old_br = (char*)(CALL_MORECORE(0));
4414
if (old_br == sp->base + sp->size) {
4415
char* rel_br = (char*)(CALL_MORECORE(-extra));
4416
char* new_br = (char*)(CALL_MORECORE(0));
4417
if (rel_br != CMFAIL && new_br < old_br)
4418
released = old_br - new_br;
4419
}
4420
}
4421
RELEASE_MALLOC_GLOBAL_LOCK();
4422
#endif
4423
}
4424
}
4425
4426
if (released != 0) {
4427
sp->size -= released;
4428
m->footprint -= released;
4429
init_top(m, m->top, m->topsize - released);
4430
check_top_chunk(m, m->top);
4431
}
4432
}
4433
4434
/* Unmap any unused mmapped segments */
4435
if (HAVE_MMAP)
4436
released += release_unused_segments(m);
4437
4438
/* On failure, disable autotrim to avoid repeated failed future calls */
4439
if (released == 0 && m->topsize > m->trim_check)
4440
m->trim_check = MAX_SIZE_T;
4441
}
4442
4443
return (released != 0)? 1 : 0;
4444
}
4445
4446
/* Consolidate and bin a chunk. Differs from exported versions
4447
of free mainly in that the chunk need not be marked as inuse.
4448
*/
4449
static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
4450
mchunkptr next = chunk_plus_offset(p, psize);
4451
if (!pinuse(p)) {
4452
mchunkptr prev;
4453
size_t prevsize = p->prev_foot;
4454
if (is_mmapped(p)) {
4455
psize += prevsize + MMAP_FOOT_PAD;
4456
if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
4457
m->footprint -= psize;
4458
return;
4459
}
4460
prev = chunk_minus_offset(p, prevsize);
4461
psize += prevsize;
4462
p = prev;
4463
if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */
4464
if (p != m->dv) {
4465
unlink_chunk(m, p, prevsize);
4466
}
4467
else if ((next->head & INUSE_BITS) == INUSE_BITS) {
4468
m->dvsize = psize;
4469
set_free_with_pinuse(p, psize, next);
4470
return;
4471
}
4472
}
4473
else {
4474
CORRUPTION_ERROR_ACTION(m);
4475
return;
4476
}
4477
}
4478
if (RTCHECK(ok_address(m, next))) {
4479
if (!cinuse(next)) { /* consolidate forward */
4480
if (next == m->top) {
4481
size_t tsize = m->topsize += psize;
4482
m->top = p;
4483
p->head = tsize | PINUSE_BIT;
4484
if (p == m->dv) {
4485
m->dv = 0;
4486
m->dvsize = 0;
4487
}
4488
return;
4489
}
4490
else if (next == m->dv) {
4491
size_t dsize = m->dvsize += psize;
4492
m->dv = p;
4493
set_size_and_pinuse_of_free_chunk(p, dsize);
4494
return;
4495
}
4496
else {
4497
size_t nsize = chunksize(next);
4498
psize += nsize;
4499
unlink_chunk(m, next, nsize);
4500
set_size_and_pinuse_of_free_chunk(p, psize);
4501
if (p == m->dv) {
4502
m->dvsize = psize;
4503
return;
4504
}
4505
}
4506
}
4507
else {
4508
set_free_with_pinuse(p, psize, next);
4509
}
4510
insert_chunk(m, p, psize);
4511
}
4512
else {
4513
CORRUPTION_ERROR_ACTION(m);
4514
}
4515
}
4516
4517
/* ---------------------------- malloc --------------------------- */
4518
4519
/* allocate a large request from the best fitting chunk in a treebin */
4520
static void* tmalloc_large(mstate m, size_t nb) {
4521
tchunkptr v = 0;
4522
size_t rsize = -nb; /* Unsigned negation */
4523
tchunkptr t;
4524
bindex_t idx;
4525
compute_tree_index(nb, idx);
4526
if ((t = *treebin_at(m, idx)) != 0) {
4527
/* Traverse tree for this bin looking for node with size == nb */
4528
size_t sizebits = nb << leftshift_for_tree_index(idx);
4529
tchunkptr rst = 0; /* The deepest untaken right subtree */
4530
for (;;) {
4531
tchunkptr rt;
4532
size_t trem = chunksize(t) - nb;
4533
if (trem < rsize) {
4534
v = t;
4535
if ((rsize = trem) == 0)
4536
break;
4537
}
4538
rt = t->child[1];
4539
t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
4540
if (rt != 0 && rt != t)
4541
rst = rt;
4542
if (t == 0) {
4543
t = rst; /* set t to least subtree holding sizes > nb */
4544
break;
4545
}
4546
sizebits <<= 1;
4547
}
4548
}
4549
if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
4550
binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
4551
if (leftbits != 0) {
4552
bindex_t i;
4553
binmap_t leastbit = least_bit(leftbits);
4554
compute_bit2idx(leastbit, i);
4555
t = *treebin_at(m, i);
4556
}
4557
}
4558
4559
while (t != 0) { /* find smallest of tree or subtree */
4560
size_t trem = chunksize(t) - nb;
4561
if (trem < rsize) {
4562
rsize = trem;
4563
v = t;
4564
}
4565
t = leftmost_child(t);
4566
}
4567
4568
/* If dv is a better fit, return 0 so malloc will use it */
4569
if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
4570
if (RTCHECK(ok_address(m, v))) { /* split */
4571
mchunkptr r = chunk_plus_offset(v, nb);
4572
assert(chunksize(v) == rsize + nb);
4573
if (RTCHECK(ok_next(v, r))) {
4574
unlink_large_chunk(m, v);
4575
if (rsize < MIN_CHUNK_SIZE)
4576
set_inuse_and_pinuse(m, v, (rsize + nb));
4577
else {
4578
set_size_and_pinuse_of_inuse_chunk(m, v, nb);
4579
set_size_and_pinuse_of_free_chunk(r, rsize);
4580
insert_chunk(m, r, rsize);
4581
}
4582
return chunk2mem(v);
4583
}
4584
}
4585
CORRUPTION_ERROR_ACTION(m);
4586
}
4587
return 0;
4588
}
4589
4590
/* allocate a small request from the best fitting chunk in a treebin */
4591
static void* tmalloc_small(mstate m, size_t nb) {
4592
tchunkptr t, v;
4593
size_t rsize;
4594
bindex_t i;
4595
binmap_t leastbit = least_bit(m->treemap);
4596
compute_bit2idx(leastbit, i);
4597
v = t = *treebin_at(m, i);
4598
rsize = chunksize(t) - nb;
4599
4600
while ((t = leftmost_child(t)) != 0) {
4601
size_t trem = chunksize(t) - nb;
4602
if (trem < rsize) {
4603
rsize = trem;
4604
v = t;
4605
}
4606
}
4607
4608
if (RTCHECK(ok_address(m, v))) {
4609
mchunkptr r = chunk_plus_offset(v, nb);
4610
assert(chunksize(v) == rsize + nb);
4611
if (RTCHECK(ok_next(v, r))) {
4612
unlink_large_chunk(m, v);
4613
if (rsize < MIN_CHUNK_SIZE)
4614
set_inuse_and_pinuse(m, v, (rsize + nb));
4615
else {
4616
set_size_and_pinuse_of_inuse_chunk(m, v, nb);
4617
set_size_and_pinuse_of_free_chunk(r, rsize);
4618
replace_dv(m, r, rsize);
4619
}
4620
return chunk2mem(v);
4621
}
4622
}
4623
4624
CORRUPTION_ERROR_ACTION(m);
4625
return 0;
4626
}
4627
4628
#if !ONLY_MSPACES
4629
4630
void* dlmalloc(size_t bytes) {
4631
/*
4632
Basic algorithm:
4633
If a small request (< 256 bytes minus per-chunk overhead):
4634
1. If one exists, use a remainderless chunk in associated smallbin.
4635
(Remainderless means that there are too few excess bytes to
4636
represent as a chunk.)
4637
2. If it is big enough, use the dv chunk, which is normally the
4638
chunk adjacent to the one used for the most recent small request.
4639
3. If one exists, split the smallest available chunk in a bin,
4640
saving remainder in dv.
4641
4. If it is big enough, use the top chunk.
4642
5. If available, get memory from system and use it
4643
Otherwise, for a large request:
4644
1. Find the smallest available binned chunk that fits, and use it
4645
if it is better fitting than dv chunk, splitting if necessary.
4646
2. If better fitting than any binned chunk, use the dv chunk.
4647
3. If it is big enough, use the top chunk.
4648
4. If request size >= mmap threshold, try to directly mmap this chunk.
4649
5. If available, get memory from system and use it
4650
4651
The ugly goto's here ensure that postaction occurs along all paths.
4652
*/
4653
4654
#if USE_LOCKS
4655
ensure_initialization(); /* initialize in sys_alloc if not using locks */
4656
#endif
4657
4658
if (!PREACTION(gm)) {
4659
void* mem;
4660
size_t nb;
4661
if (bytes <= MAX_SMALL_REQUEST) {
4662
bindex_t idx;
4663
binmap_t smallbits;
4664
nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
4665
idx = small_index(nb);
4666
smallbits = gm->smallmap >> idx;
4667
4668
if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
4669
mchunkptr b, p;
4670
idx += ~smallbits & 1; /* Uses next bin if idx empty */
4671
b = smallbin_at(gm, idx);
4672
p = b->fd;
4673
assert(chunksize(p) == small_index2size(idx));
4674
unlink_first_small_chunk(gm, b, p, idx);
4675
set_inuse_and_pinuse(gm, p, small_index2size(idx));
4676
mem = chunk2mem(p);
4677
check_malloced_chunk(gm, mem, nb);
4678
goto postaction;
4679
}
4680
4681
else if (nb > gm->dvsize) {
4682
if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
4683
mchunkptr b, p, r;
4684
size_t rsize;
4685
bindex_t i;
4686
binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
4687
binmap_t leastbit = least_bit(leftbits);
4688
compute_bit2idx(leastbit, i);
4689
b = smallbin_at(gm, i);
4690
p = b->fd;
4691
assert(chunksize(p) == small_index2size(i));
4692
unlink_first_small_chunk(gm, b, p, i);
4693
rsize = small_index2size(i) - nb;
4694
/* Fit here cannot be remainderless if 4byte sizes */
4695
if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
4696
set_inuse_and_pinuse(gm, p, small_index2size(i));
4697
else {
4698
set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
4699
r = chunk_plus_offset(p, nb);
4700
set_size_and_pinuse_of_free_chunk(r, rsize);
4701
replace_dv(gm, r, rsize);
4702
}
4703
mem = chunk2mem(p);
4704
check_malloced_chunk(gm, mem, nb);
4705
goto postaction;
4706
}
4707
4708
else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
4709
check_malloced_chunk(gm, mem, nb);
4710
goto postaction;
4711
}
4712
}
4713
}
4714
else if (bytes >= MAX_REQUEST)
4715
nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
4716
else {
4717
nb = pad_request(bytes);
4718
if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
4719
check_malloced_chunk(gm, mem, nb);
4720
goto postaction;
4721
}
4722
}
4723
4724
if (nb <= gm->dvsize) {
4725
size_t rsize = gm->dvsize - nb;
4726
mchunkptr p = gm->dv;
4727
if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
4728
mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
4729
gm->dvsize = rsize;
4730
set_size_and_pinuse_of_free_chunk(r, rsize);
4731
set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
4732
}
4733
else { /* exhaust dv */
4734
size_t dvs = gm->dvsize;
4735
gm->dvsize = 0;
4736
gm->dv = 0;
4737
set_inuse_and_pinuse(gm, p, dvs);
4738
}
4739
mem = chunk2mem(p);
4740
check_malloced_chunk(gm, mem, nb);
4741
goto postaction;
4742
}
4743
4744
else if (nb < gm->topsize) { /* Split top */
4745
size_t rsize = gm->topsize -= nb;
4746
mchunkptr p = gm->top;
4747
mchunkptr r = gm->top = chunk_plus_offset(p, nb);
4748
r->head = rsize | PINUSE_BIT;
4749
set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
4750
mem = chunk2mem(p);
4751
check_top_chunk(gm, gm->top);
4752
check_malloced_chunk(gm, mem, nb);
4753
goto postaction;
4754
}
4755
4756
mem = sys_alloc(gm, nb);
4757
4758
postaction:
4759
POSTACTION(gm);
4760
#if __EMSCRIPTEN__
4761
/* XXX Emscripten Tracing API. */
4762
emscripten_trace_record_allocation(mem, bytes);
4763
#endif
4764
return mem;
4765
}
4766
4767
return 0;
4768
}
4769
4770
/* ---------------------------- free --------------------------- */
4771
4772
void dlfree(void* mem) {
4773
/*
4774
Consolidate freed chunks with preceeding or succeeding bordering
4775
free chunks, if they exist, and then place in a bin. Intermixed
4776
with special cases for top, dv, mmapped chunks, and usage errors.
4777
*/
4778
4779
if (mem != 0) {
4780
#if __EMSCRIPTEN__
4781
/* XXX Emscripten Tracing API. */
4782
emscripten_trace_record_free(mem);
4783
#endif
4784
mchunkptr p = mem2chunk(mem);
4785
#if FOOTERS
4786
mstate fm = get_mstate_for(p);
4787
if (!ok_magic(fm)) {
4788
USAGE_ERROR_ACTION(fm, p);
4789
return;
4790
}
4791
#else /* FOOTERS */
4792
#define fm gm
4793
#endif /* FOOTERS */
4794
if (!PREACTION(fm)) {
4795
check_inuse_chunk(fm, p);
4796
if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
4797
size_t psize = chunksize(p);
4798
mchunkptr next = chunk_plus_offset(p, psize);
4799
if (!pinuse(p)) {
4800
size_t prevsize = p->prev_foot;
4801
if (is_mmapped(p)) {
4802
psize += prevsize + MMAP_FOOT_PAD;
4803
if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
4804
fm->footprint -= psize;
4805
goto postaction;
4806
}
4807
else {
4808
mchunkptr prev = chunk_minus_offset(p, prevsize);
4809
psize += prevsize;
4810
p = prev;
4811
if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
4812
if (p != fm->dv) {
4813
unlink_chunk(fm, p, prevsize);
4814
}
4815
else if ((next->head & INUSE_BITS) == INUSE_BITS) {
4816
fm->dvsize = psize;
4817
set_free_with_pinuse(p, psize, next);
4818
goto postaction;
4819
}
4820
}
4821
else
4822
goto erroraction;
4823
}
4824
}
4825
4826
if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
4827
if (!cinuse(next)) { /* consolidate forward */
4828
if (next == fm->top) {
4829
size_t tsize = fm->topsize += psize;
4830
fm->top = p;
4831
p->head = tsize | PINUSE_BIT;
4832
if (p == fm->dv) {
4833
fm->dv = 0;
4834
fm->dvsize = 0;
4835
}
4836
if (should_trim(fm, tsize))
4837
sys_trim(fm, 0);
4838
goto postaction;
4839
}
4840
else if (next == fm->dv) {
4841
size_t dsize = fm->dvsize += psize;
4842
fm->dv = p;
4843
set_size_and_pinuse_of_free_chunk(p, dsize);
4844
goto postaction;
4845
}
4846
else {
4847
size_t nsize = chunksize(next);
4848
psize += nsize;
4849
unlink_chunk(fm, next, nsize);
4850
set_size_and_pinuse_of_free_chunk(p, psize);
4851
if (p == fm->dv) {
4852
fm->dvsize = psize;
4853
goto postaction;
4854
}
4855
}
4856
}
4857
else
4858
set_free_with_pinuse(p, psize, next);
4859
4860
if (is_small(psize)) {
4861
insert_small_chunk(fm, p, psize);
4862
check_free_chunk(fm, p);
4863
}
4864
else {
4865
tchunkptr tp = (tchunkptr)p;
4866
insert_large_chunk(fm, tp, psize);
4867
check_free_chunk(fm, p);
4868
if (--fm->release_checks == 0)
4869
release_unused_segments(fm);
4870
}
4871
goto postaction;
4872
}
4873
}
4874
erroraction:
4875
USAGE_ERROR_ACTION(fm, p);
4876
postaction:
4877
POSTACTION(fm);
4878
}
4879
}
4880
#if !FOOTERS
4881
#undef fm
4882
#endif /* FOOTERS */
4883
}
4884
4885
void* dlcalloc(size_t n_elements, size_t elem_size) {
4886
void* mem;
4887
size_t req = 0;
4888
if (n_elements != 0) {
4889
req = n_elements * elem_size;
4890
if (((n_elements | elem_size) & ~(size_t)0xffff) &&
4891
(req / n_elements != elem_size))
4892
req = MAX_SIZE_T; /* force downstream failure on overflow */
4893
}
4894
mem = dlmalloc(req);
4895
if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
4896
memset(mem, 0, req);
4897
return mem;
4898
}
4899
4900
#endif /* !ONLY_MSPACES */
4901
4902
/* ------------ Internal support for realloc, memalign, etc -------------- */
4903
4904
/* Try to realloc; only in-place unless can_move true */
4905
static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
4906
int can_move) {
4907
mchunkptr newp = 0;
4908
size_t oldsize = chunksize(p);
4909
mchunkptr next = chunk_plus_offset(p, oldsize);
4910
if (RTCHECK(ok_address(m, p) && ok_inuse(p) &&
4911
ok_next(p, next) && ok_pinuse(next))) {
4912
if (is_mmapped(p)) {
4913
newp = mmap_resize(m, p, nb, can_move);
4914
}
4915
else if (oldsize >= nb) { /* already big enough */
4916
size_t rsize = oldsize - nb;
4917
if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */
4918
mchunkptr r = chunk_plus_offset(p, nb);
4919
set_inuse(m, p, nb);
4920
set_inuse(m, r, rsize);
4921
dispose_chunk(m, r, rsize);
4922
}
4923
newp = p;
4924
}
4925
else if (next == m->top) { /* extend into top */
4926
if (oldsize + m->topsize > nb) {
4927
size_t newsize = oldsize + m->topsize;
4928
size_t newtopsize = newsize - nb;
4929
mchunkptr newtop = chunk_plus_offset(p, nb);
4930
set_inuse(m, p, nb);
4931
newtop->head = newtopsize |PINUSE_BIT;
4932
m->top = newtop;
4933
m->topsize = newtopsize;
4934
newp = p;
4935
}
4936
}
4937
else if (next == m->dv) { /* extend into dv */
4938
size_t dvs = m->dvsize;
4939
if (oldsize + dvs >= nb) {
4940
size_t dsize = oldsize + dvs - nb;
4941
if (dsize >= MIN_CHUNK_SIZE) {
4942
mchunkptr r = chunk_plus_offset(p, nb);
4943
mchunkptr n = chunk_plus_offset(r, dsize);
4944
set_inuse(m, p, nb);
4945
set_size_and_pinuse_of_free_chunk(r, dsize);
4946
clear_pinuse(n);
4947
m->dvsize = dsize;
4948
m->dv = r;
4949
}
4950
else { /* exhaust dv */
4951
size_t newsize = oldsize + dvs;
4952
set_inuse(m, p, newsize);
4953
m->dvsize = 0;
4954
m->dv = 0;
4955
}
4956
newp = p;
4957
}
4958
}
4959
else if (!cinuse(next)) { /* extend into next free chunk */
4960
size_t nextsize = chunksize(next);
4961
if (oldsize + nextsize >= nb) {
4962
size_t rsize = oldsize + nextsize - nb;
4963
unlink_chunk(m, next, nextsize);
4964
if (rsize < MIN_CHUNK_SIZE) {
4965
size_t newsize = oldsize + nextsize;
4966
set_inuse(m, p, newsize);
4967
}
4968
else {
4969
mchunkptr r = chunk_plus_offset(p, nb);
4970
set_inuse(m, p, nb);
4971
set_inuse(m, r, rsize);
4972
dispose_chunk(m, r, rsize);
4973
}
4974
newp = p;
4975
}
4976
}
4977
}
4978
else {
4979
USAGE_ERROR_ACTION(m, chunk2mem(p));
4980
}
4981
return newp;
4982
}
4983
4984
static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
4985
void* mem = 0;
4986
if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
4987
alignment = MIN_CHUNK_SIZE;
4988
if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
4989
size_t a = MALLOC_ALIGNMENT << 1;
4990
while (a < alignment) a <<= 1;
4991
alignment = a;
4992
}
4993
if (bytes >= MAX_REQUEST - alignment) {
4994
if (m != 0) { /* Test isn't needed but avoids compiler warning */
4995
MALLOC_FAILURE_ACTION;
4996
}
4997
}
4998
else {
4999
size_t nb = request2size(bytes);
5000
size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
5001
mem = internal_malloc(m, req);
5002
if (mem != 0) {
5003
mchunkptr p = mem2chunk(mem);
5004
if (PREACTION(m))
5005
return 0;
5006
if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */
5007
/*
5008
Find an aligned spot inside chunk. Since we need to give
5009
back leading space in a chunk of at least MIN_CHUNK_SIZE, if
5010
the first calculation places us at a spot with less than
5011
MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
5012
We've allocated enough total room so that this is always
5013
possible.
5014
*/
5015
char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment -
5016
SIZE_T_ONE)) &
5017
-alignment));
5018
char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
5019
br : br+alignment;
5020
mchunkptr newp = (mchunkptr)pos;
5021
size_t leadsize = pos - (char*)(p);
5022
size_t newsize = chunksize(p) - leadsize;
5023
5024
if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
5025
newp->prev_foot = p->prev_foot + leadsize;
5026
newp->head = newsize;
5027
}
5028
else { /* Otherwise, give back leader, use the rest */
5029
set_inuse(m, newp, newsize);
5030
set_inuse(m, p, leadsize);
5031
dispose_chunk(m, p, leadsize);
5032
}
5033
p = newp;
5034
}
5035
5036
/* Give back spare room at the end */
5037
if (!is_mmapped(p)) {
5038
size_t size = chunksize(p);
5039
if (size > nb + MIN_CHUNK_SIZE) {
5040
size_t remainder_size = size - nb;
5041
mchunkptr remainder = chunk_plus_offset(p, nb);
5042
set_inuse(m, p, nb);
5043
set_inuse(m, remainder, remainder_size);
5044
dispose_chunk(m, remainder, remainder_size);
5045
}
5046
}
5047
5048
mem = chunk2mem(p);
5049
assert (chunksize(p) >= nb);
5050
assert(((size_t)mem & (alignment - 1)) == 0);
5051
check_inuse_chunk(m, p);
5052
POSTACTION(m);
5053
}
5054
}
5055
return mem;
5056
}
5057
5058
/*
5059
Common support for independent_X routines, handling
5060
all of the combinations that can result.
5061
The opts arg has:
5062
bit 0 set if all elements are same size (using sizes[0])
5063
bit 1 set if elements should be zeroed
5064
*/
5065
static void** ialloc(mstate m,
5066
size_t n_elements,
5067
size_t* sizes,
5068
int opts,
5069
void* chunks[]) {
5070
5071
size_t element_size; /* chunksize of each element, if all same */
5072
size_t contents_size; /* total size of elements */
5073
size_t array_size; /* request size of pointer array */
5074
void* mem; /* malloced aggregate space */
5075
mchunkptr p; /* corresponding chunk */
5076
size_t remainder_size; /* remaining bytes while splitting */
5077
void** marray; /* either "chunks" or malloced ptr array */
5078
mchunkptr array_chunk; /* chunk for malloced ptr array */
5079
flag_t was_enabled; /* to disable mmap */
5080
size_t size;
5081
size_t i;
5082
5083
ensure_initialization();
5084
/* compute array length, if needed */
5085
if (chunks != 0) {
5086
if (n_elements == 0)
5087
return chunks; /* nothing to do */
5088
marray = chunks;
5089
array_size = 0;
5090
}
5091
else {
5092
/* if empty req, must still return chunk representing empty array */
5093
if (n_elements == 0)
5094
return (void**)internal_malloc(m, 0);
5095
marray = 0;
5096
array_size = request2size(n_elements * (sizeof(void*)));
5097
}
5098
5099
/* compute total element size */
5100
if (opts & 0x1) { /* all-same-size */
5101
element_size = request2size(*sizes);
5102
contents_size = n_elements * element_size;
5103
}
5104
else { /* add up all the sizes */
5105
element_size = 0;
5106
contents_size = 0;
5107
for (i = 0; i != n_elements; ++i)
5108
contents_size += request2size(sizes[i]);
5109
}
5110
5111
size = contents_size + array_size;
5112
5113
/*
5114
Allocate the aggregate chunk. First disable direct-mmapping so
5115
malloc won't use it, since we would not be able to later
5116
free/realloc space internal to a segregated mmap region.
5117
*/
5118
was_enabled = use_mmap(m);
5119
disable_mmap(m);
5120
mem = internal_malloc(m, size - CHUNK_OVERHEAD);
5121
if (was_enabled)
5122
enable_mmap(m);
5123
if (mem == 0)
5124
return 0;
5125
5126
if (PREACTION(m)) return 0;
5127
p = mem2chunk(mem);
5128
remainder_size = chunksize(p);
5129
5130
assert(!is_mmapped(p));
5131
5132
if (opts & 0x2) { /* optionally clear the elements */
5133
memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
5134
}
5135
5136
/* If not provided, allocate the pointer array as final part of chunk */
5137
if (marray == 0) {
5138
size_t array_chunk_size;
5139
array_chunk = chunk_plus_offset(p, contents_size);
5140
array_chunk_size = remainder_size - contents_size;
5141
marray = (void**) (chunk2mem(array_chunk));
5142
set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
5143
remainder_size = contents_size;
5144
}
5145
5146
/* split out elements */
5147
for (i = 0; ; ++i) {
5148
marray[i] = chunk2mem(p);
5149
if (i != n_elements-1) {
5150
if (element_size != 0)
5151
size = element_size;
5152
else
5153
size = request2size(sizes[i]);
5154
remainder_size -= size;
5155
set_size_and_pinuse_of_inuse_chunk(m, p, size);
5156
p = chunk_plus_offset(p, size);
5157
}
5158
else { /* the final element absorbs any overallocation slop */
5159
set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
5160
break;
5161
}
5162
}
5163
5164
#if DEBUG
5165
if (marray != chunks) {
5166
/* final element must have exactly exhausted chunk */
5167
if (element_size != 0) {
5168
assert(remainder_size == element_size);
5169
}
5170
else {
5171
assert(remainder_size == request2size(sizes[i]));
5172
}
5173
check_inuse_chunk(m, mem2chunk(marray));
5174
}
5175
for (i = 0; i != n_elements; ++i)
5176
check_inuse_chunk(m, mem2chunk(marray[i]));
5177
5178
#endif /* DEBUG */
5179
5180
POSTACTION(m);
5181
return marray;
5182
}
5183
5184
/* Try to free all pointers in the given array.
5185
Note: this could be made faster, by delaying consolidation,
5186
at the price of disabling some user integrity checks, We
5187
still optimize some consolidations by combining adjacent
5188
chunks before freeing, which will occur often if allocated
5189
with ialloc or the array is sorted.
5190
*/
5191
static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {
5192
size_t unfreed = 0;
5193
if (!PREACTION(m)) {
5194
void** a;
5195
void** fence = &(array[nelem]);
5196
for (a = array; a != fence; ++a) {
5197
void* mem = *a;
5198
if (mem != 0) {
5199
mchunkptr p = mem2chunk(mem);
5200
size_t psize = chunksize(p);
5201
#if FOOTERS
5202
if (get_mstate_for(p) != m) {
5203
++unfreed;
5204
continue;
5205
}
5206
#endif
5207
check_inuse_chunk(m, p);
5208
*a = 0;
5209
if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {
5210
void ** b = a + 1; /* try to merge with next chunk */
5211
mchunkptr next = next_chunk(p);
5212
if (b != fence && *b == chunk2mem(next)) {
5213
size_t newsize = chunksize(next) + psize;
5214
set_inuse(m, p, newsize);
5215
*b = chunk2mem(p);
5216
}
5217
else
5218
dispose_chunk(m, p, psize);
5219
}
5220
else {
5221
CORRUPTION_ERROR_ACTION(m);
5222
break;
5223
}
5224
}
5225
}
5226
if (should_trim(m, m->topsize))
5227
sys_trim(m, 0);
5228
POSTACTION(m);
5229
}
5230
return unfreed;
5231
}
5232
5233
/* Traversal */
5234
#if MALLOC_INSPECT_ALL
5235
static void internal_inspect_all(mstate m,
5236
void(*handler)(void *start,
5237
void *end,
5238
size_t used_bytes,
5239
void* callback_arg),
5240
void* arg) {
5241
if (is_initialized(m)) {
5242
mchunkptr top = m->top;
5243
msegmentptr s;
5244
for (s = &m->seg; s != 0; s = s->next) {
5245
mchunkptr q = align_as_chunk(s->base);
5246
while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {
5247
mchunkptr next = next_chunk(q);
5248
size_t sz = chunksize(q);
5249
size_t used;
5250
void* start;
5251
if (is_inuse(q)) {
5252
used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
5253
start = chunk2mem(q);
5254
}
5255
else {
5256
used = 0;
5257
if (is_small(sz)) { /* offset by possible bookkeeping */
5258
start = (void*)((char*)q + sizeof(struct malloc_chunk));
5259
}
5260
else {
5261
start = (void*)((char*)q + sizeof(struct malloc_tree_chunk));
5262
}
5263
}
5264
if (start < (void*)next) /* skip if all space is bookkeeping */
5265
handler(start, next, used, arg);
5266
if (q == top)
5267
break;
5268
q = next;
5269
}
5270
}
5271
}
5272
}
5273
#endif /* MALLOC_INSPECT_ALL */
5274
5275
/* ------------------ Exported realloc, memalign, etc -------------------- */
5276
5277
#if !ONLY_MSPACES
5278
5279
void* dlrealloc(void* oldmem, size_t bytes) {
5280
void* mem = 0;
5281
if (oldmem == 0) {
5282
mem = dlmalloc(bytes);
5283
}
5284
else if (bytes >= MAX_REQUEST) {
5285
MALLOC_FAILURE_ACTION;
5286
}
5287
#ifdef REALLOC_ZERO_BYTES_FREES
5288
else if (bytes == 0) {
5289
dlfree(oldmem);
5290
}
5291
#endif /* REALLOC_ZERO_BYTES_FREES */
5292
else {
5293
size_t nb = request2size(bytes);
5294
mchunkptr oldp = mem2chunk(oldmem);
5295
#if ! FOOTERS
5296
mstate m = gm;
5297
#else /* FOOTERS */
5298
mstate m = get_mstate_for(oldp);
5299
if (!ok_magic(m)) {
5300
USAGE_ERROR_ACTION(m, oldmem);
5301
return 0;
5302
}
5303
#endif /* FOOTERS */
5304
if (!PREACTION(m)) {
5305
mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
5306
POSTACTION(m);
5307
if (newp != 0) {
5308
check_inuse_chunk(m, newp);
5309
mem = chunk2mem(newp);
5310
#if __EMSCRIPTEN__
5311
/* XXX Emscripten Tracing API. */
5312
emscripten_trace_record_reallocation(oldmem, mem, bytes);
5313
#endif
5314
}
5315
else {
5316
mem = internal_malloc(m, bytes);
5317
if (mem != 0) {
5318
size_t oc = chunksize(oldp) - overhead_for(oldp);
5319
memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
5320
internal_free(m, oldmem);
5321
}
5322
}
5323
}
5324
}
5325
return mem;
5326
}
5327
5328
void* dlrealloc_in_place(void* oldmem, size_t bytes) {
5329
void* mem = 0;
5330
if (oldmem != 0) {
5331
if (bytes >= MAX_REQUEST) {
5332
MALLOC_FAILURE_ACTION;
5333
}
5334
else {
5335
size_t nb = request2size(bytes);
5336
mchunkptr oldp = mem2chunk(oldmem);
5337
#if ! FOOTERS
5338
mstate m = gm;
5339
#else /* FOOTERS */
5340
mstate m = get_mstate_for(oldp);
5341
if (!ok_magic(m)) {
5342
USAGE_ERROR_ACTION(m, oldmem);
5343
return 0;
5344
}
5345
#endif /* FOOTERS */
5346
if (!PREACTION(m)) {
5347
mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
5348
POSTACTION(m);
5349
if (newp == oldp) {
5350
check_inuse_chunk(m, newp);
5351
mem = oldmem;
5352
}
5353
}
5354
}
5355
}
5356
#if __EMSCRIPTEN__
5357
/* XXX Emscripten Tracing API. */
5358
emscripten_trace_record_reallocation(oldmem, mem, bytes);
5359
#endif
5360
return mem;
5361
}
5362
5363
void* dlmemalign(size_t alignment, size_t bytes) {
5364
if (alignment <= MALLOC_ALIGNMENT) {
5365
return dlmalloc(bytes);
5366
}
5367
return internal_memalign(gm, alignment, bytes);
5368
}
5369
5370
int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {
5371
void* mem = 0;
5372
if (alignment == MALLOC_ALIGNMENT)
5373
mem = dlmalloc(bytes);
5374
else {
5375
size_t d = alignment / sizeof(void*);
5376
size_t r = alignment % sizeof(void*);
5377
if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0)
5378
return EINVAL;
5379
else if (bytes <= MAX_REQUEST - alignment) {
5380
if (alignment < MIN_CHUNK_SIZE)
5381
alignment = MIN_CHUNK_SIZE;
5382
mem = internal_memalign(gm, alignment, bytes);
5383
}
5384
}
5385
if (mem == 0)
5386
return ENOMEM;
5387
else {
5388
*pp = mem;
5389
return 0;
5390
}
5391
}
5392
5393
void* dlvalloc(size_t bytes) {
5394
size_t pagesz;
5395
ensure_initialization();
5396
pagesz = mparams.page_size;
5397
return dlmemalign(pagesz, bytes);
5398
}
5399
5400
void* dlpvalloc(size_t bytes) {
5401
size_t pagesz;
5402
ensure_initialization();
5403
pagesz = mparams.page_size;
5404
return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
5405
}
5406
5407
void** dlindependent_calloc(size_t n_elements, size_t elem_size,
5408
void* chunks[]) {
5409
size_t sz = elem_size; /* serves as 1-element array */
5410
return ialloc(gm, n_elements, &sz, 3, chunks);
5411
}
5412
5413
void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
5414
void* chunks[]) {
5415
return ialloc(gm, n_elements, sizes, 0, chunks);
5416
}
5417
5418
size_t dlbulk_free(void* array[], size_t nelem) {
5419
return internal_bulk_free(gm, array, nelem);
5420
}
5421
5422
#if MALLOC_INSPECT_ALL
5423
void dlmalloc_inspect_all(void(*handler)(void *start,
5424
void *end,
5425
size_t used_bytes,
5426
void* callback_arg),
5427
void* arg) {
5428
ensure_initialization();
5429
if (!PREACTION(gm)) {
5430
internal_inspect_all(gm, handler, arg);
5431
POSTACTION(gm);
5432
}
5433
}
5434
#endif /* MALLOC_INSPECT_ALL */
5435
5436
int dlmalloc_trim(size_t pad) {
5437
int result = 0;
5438
ensure_initialization();
5439
if (!PREACTION(gm)) {
5440
result = sys_trim(gm, pad);
5441
POSTACTION(gm);
5442
}
5443
return result;
5444
}
5445
5446
size_t dlmalloc_footprint(void) {
5447
return gm->footprint;
5448
}
5449
5450
size_t dlmalloc_max_footprint(void) {
5451
return gm->max_footprint;
5452
}
5453
5454
size_t dlmalloc_footprint_limit(void) {
5455
size_t maf = gm->footprint_limit;
5456
return maf == 0 ? MAX_SIZE_T : maf;
5457
}
5458
5459
size_t dlmalloc_set_footprint_limit(size_t bytes) {
5460
size_t result; /* invert sense of 0 */
5461
if (bytes == 0)
5462
result = granularity_align(1); /* Use minimal size */
5463
if (bytes == MAX_SIZE_T)
5464
result = 0; /* disable */
5465
else
5466
result = granularity_align(bytes);
5467
return gm->footprint_limit = result;
5468
}
5469
5470
#if !NO_MALLINFO
5471
struct mallinfo dlmallinfo(void) {
5472
return internal_mallinfo(gm);
5473
}
5474
#endif /* NO_MALLINFO */
5475
5476
#if !NO_MALLOC_STATS
5477
void dlmalloc_stats() {
5478
internal_malloc_stats(gm);
5479
}
5480
#endif /* NO_MALLOC_STATS */
5481
5482
int dlmallopt(int param_number, int value) {
5483
return change_mparam(param_number, value);
5484
}
5485
5486
size_t dlmalloc_usable_size(void* mem) {
5487
if (mem != 0) {
5488
mchunkptr p = mem2chunk(mem);
5489
if (is_inuse(p))
5490
return chunksize(p) - overhead_for(p);
5491
}
5492
return 0;
5493
}
5494
5495
#endif /* !ONLY_MSPACES */
5496
5497
/* ----------------------------- user mspaces ---------------------------- */
5498
5499
#if MSPACES
5500
5501
static mstate init_user_mstate(char* tbase, size_t tsize) {
5502
size_t msize = pad_request(sizeof(struct malloc_state));
5503
mchunkptr mn;
5504
mchunkptr msp = align_as_chunk(tbase);
5505
mstate m = (mstate)(chunk2mem(msp));
5506
memset(m, 0, msize);
5507
(void)INITIAL_LOCK(&m->mutex);
5508
msp->head = (msize|INUSE_BITS);
5509
m->seg.base = m->least_addr = tbase;
5510
m->seg.size = m->footprint = m->max_footprint = tsize;
5511
m->magic = mparams.magic;
5512
m->release_checks = MAX_RELEASE_CHECK_RATE;
5513
m->mflags = mparams.default_mflags;
5514
m->extp = 0;
5515
m->exts = 0;
5516
disable_contiguous(m);
5517
init_bins(m);
5518
mn = next_chunk(mem2chunk(m));
5519
init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
5520
check_top_chunk(m, m->top);
5521
return m;
5522
}
5523
5524
mspace create_mspace(size_t capacity, int locked) {
5525
mstate m = 0;
5526
size_t msize;
5527
ensure_initialization();
5528
msize = pad_request(sizeof(struct malloc_state));
5529
if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
5530
size_t rs = ((capacity == 0)? mparams.granularity :
5531
(capacity + TOP_FOOT_SIZE + msize));
5532
size_t tsize = granularity_align(rs);
5533
char* tbase = (char*)(CALL_MMAP(tsize));
5534
if (tbase != CMFAIL) {
5535
m = init_user_mstate(tbase, tsize);
5536
m->seg.sflags = USE_MMAP_BIT;
5537
set_lock(m, locked);
5538
}
5539
}
5540
return (mspace)m;
5541
}
5542
5543
mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
5544
mstate m = 0;
5545
size_t msize;
5546
ensure_initialization();
5547
msize = pad_request(sizeof(struct malloc_state));
5548
if (capacity > msize + TOP_FOOT_SIZE &&
5549
capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
5550
m = init_user_mstate((char*)base, capacity);
5551
m->seg.sflags = EXTERN_BIT;
5552
set_lock(m, locked);
5553
}
5554
return (mspace)m;
5555
}
5556
5557
int mspace_track_large_chunks(mspace msp, int enable) {
5558
int ret = 0;
5559
mstate ms = (mstate)msp;
5560
if (!PREACTION(ms)) {
5561
if (!use_mmap(ms)) {
5562
ret = 1;
5563
}
5564
if (!enable) {
5565
enable_mmap(ms);
5566
} else {
5567
disable_mmap(ms);
5568
}
5569
POSTACTION(ms);
5570
}
5571
return ret;
5572
}
5573
5574
size_t destroy_mspace(mspace msp) {
5575
size_t freed = 0;
5576
mstate ms = (mstate)msp;
5577
if (ok_magic(ms)) {
5578
msegmentptr sp = &ms->seg;
5579
(void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */
5580
while (sp != 0) {
5581
char* base = sp->base;
5582
size_t size = sp->size;
5583
flag_t flag = sp->sflags;
5584
(void)base; /* placate people compiling -Wunused-variable */
5585
sp = sp->next;
5586
if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) &&
5587
CALL_MUNMAP(base, size) == 0)
5588
freed += size;
5589
}
5590
}
5591
else {
5592
USAGE_ERROR_ACTION(ms,ms);
5593
}
5594
return freed;
5595
}
5596
5597
/*
5598
mspace versions of routines are near-clones of the global
5599
versions. This is not so nice but better than the alternatives.
5600
*/
5601
5602
void* mspace_malloc(mspace msp, size_t bytes) {
5603
mstate ms = (mstate)msp;
5604
if (!ok_magic(ms)) {
5605
USAGE_ERROR_ACTION(ms,ms);
5606
return 0;
5607
}
5608
if (!PREACTION(ms)) {
5609
void* mem;
5610
size_t nb;
5611
if (bytes <= MAX_SMALL_REQUEST) {
5612
bindex_t idx;
5613
binmap_t smallbits;
5614
nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
5615
idx = small_index(nb);
5616
smallbits = ms->smallmap >> idx;
5617
5618
if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
5619
mchunkptr b, p;
5620
idx += ~smallbits & 1; /* Uses next bin if idx empty */
5621
b = smallbin_at(ms, idx);
5622
p = b->fd;
5623
assert(chunksize(p) == small_index2size(idx));
5624
unlink_first_small_chunk(ms, b, p, idx);
5625
set_inuse_and_pinuse(ms, p, small_index2size(idx));
5626
mem = chunk2mem(p);
5627
check_malloced_chunk(ms, mem, nb);
5628
goto postaction;
5629
}
5630
5631
else if (nb > ms->dvsize) {
5632
if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
5633
mchunkptr b, p, r;
5634
size_t rsize;
5635
bindex_t i;
5636
binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
5637
binmap_t leastbit = least_bit(leftbits);
5638
compute_bit2idx(leastbit, i);
5639
b = smallbin_at(ms, i);
5640
p = b->fd;
5641
assert(chunksize(p) == small_index2size(i));
5642
unlink_first_small_chunk(ms, b, p, i);
5643
rsize = small_index2size(i) - nb;
5644
/* Fit here cannot be remainderless if 4byte sizes */
5645
if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
5646
set_inuse_and_pinuse(ms, p, small_index2size(i));
5647
else {
5648
set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
5649
r = chunk_plus_offset(p, nb);
5650
set_size_and_pinuse_of_free_chunk(r, rsize);
5651
replace_dv(ms, r, rsize);
5652
}
5653
mem = chunk2mem(p);
5654
check_malloced_chunk(ms, mem, nb);
5655
goto postaction;
5656
}
5657
5658
else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
5659
check_malloced_chunk(ms, mem, nb);
5660
goto postaction;
5661
}
5662
}
5663
}
5664
else if (bytes >= MAX_REQUEST)
5665
nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
5666
else {
5667
nb = pad_request(bytes);
5668
if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
5669
check_malloced_chunk(ms, mem, nb);
5670
goto postaction;
5671
}
5672
}
5673
5674
if (nb <= ms->dvsize) {
5675
size_t rsize = ms->dvsize - nb;
5676
mchunkptr p = ms->dv;
5677
if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
5678
mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
5679
ms->dvsize = rsize;
5680
set_size_and_pinuse_of_free_chunk(r, rsize);
5681
set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
5682
}
5683
else { /* exhaust dv */
5684
size_t dvs = ms->dvsize;
5685
ms->dvsize = 0;
5686
ms->dv = 0;
5687
set_inuse_and_pinuse(ms, p, dvs);
5688
}
5689
mem = chunk2mem(p);
5690
check_malloced_chunk(ms, mem, nb);
5691
goto postaction;
5692
}
5693
5694
else if (nb < ms->topsize) { /* Split top */
5695
size_t rsize = ms->topsize -= nb;
5696
mchunkptr p = ms->top;
5697
mchunkptr r = ms->top = chunk_plus_offset(p, nb);
5698
r->head = rsize | PINUSE_BIT;
5699
set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
5700
mem = chunk2mem(p);
5701
check_top_chunk(ms, ms->top);
5702
check_malloced_chunk(ms, mem, nb);
5703
goto postaction;
5704
}
5705
5706
mem = sys_alloc(ms, nb);
5707
5708
postaction:
5709
POSTACTION(ms);
5710
return mem;
5711
}
5712
5713
return 0;
5714
}
5715
5716
void mspace_free(mspace msp, void* mem) {
5717
if (mem != 0) {
5718
mchunkptr p = mem2chunk(mem);
5719
#if FOOTERS
5720
mstate fm = get_mstate_for(p);
5721
(void)msp; /* placate people compiling -Wunused */
5722
#else /* FOOTERS */
5723
mstate fm = (mstate)msp;
5724
#endif /* FOOTERS */
5725
if (!ok_magic(fm)) {
5726
USAGE_ERROR_ACTION(fm, p);
5727
return;
5728
}
5729
if (!PREACTION(fm)) {
5730
check_inuse_chunk(fm, p);
5731
if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
5732
size_t psize = chunksize(p);
5733
mchunkptr next = chunk_plus_offset(p, psize);
5734
if (!pinuse(p)) {
5735
size_t prevsize = p->prev_foot;
5736
if (is_mmapped(p)) {
5737
psize += prevsize + MMAP_FOOT_PAD;
5738
if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
5739
fm->footprint -= psize;
5740
goto postaction;
5741
}
5742
else {
5743
mchunkptr prev = chunk_minus_offset(p, prevsize);
5744
psize += prevsize;
5745
p = prev;
5746
if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
5747
if (p != fm->dv) {
5748
unlink_chunk(fm, p, prevsize);
5749
}
5750
else if ((next->head & INUSE_BITS) == INUSE_BITS) {
5751
fm->dvsize = psize;
5752
set_free_with_pinuse(p, psize, next);
5753
goto postaction;
5754
}
5755
}
5756
else
5757
goto erroraction;
5758
}
5759
}
5760
5761
if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
5762
if (!cinuse(next)) { /* consolidate forward */
5763
if (next == fm->top) {
5764
size_t tsize = fm->topsize += psize;
5765
fm->top = p;
5766
p->head = tsize | PINUSE_BIT;
5767
if (p == fm->dv) {
5768
fm->dv = 0;
5769
fm->dvsize = 0;
5770
}
5771
if (should_trim(fm, tsize))
5772
sys_trim(fm, 0);
5773
goto postaction;
5774
}
5775
else if (next == fm->dv) {
5776
size_t dsize = fm->dvsize += psize;
5777
fm->dv = p;
5778
set_size_and_pinuse_of_free_chunk(p, dsize);
5779
goto postaction;
5780
}
5781
else {
5782
size_t nsize = chunksize(next);
5783
psize += nsize;
5784
unlink_chunk(fm, next, nsize);
5785
set_size_and_pinuse_of_free_chunk(p, psize);
5786
if (p == fm->dv) {
5787
fm->dvsize = psize;
5788
goto postaction;
5789
}
5790
}
5791
}
5792
else
5793
set_free_with_pinuse(p, psize, next);
5794
5795
if (is_small(psize)) {
5796
insert_small_chunk(fm, p, psize);
5797
check_free_chunk(fm, p);
5798
}
5799
else {
5800
tchunkptr tp = (tchunkptr)p;
5801
insert_large_chunk(fm, tp, psize);
5802
check_free_chunk(fm, p);
5803
if (--fm->release_checks == 0)
5804
release_unused_segments(fm);
5805
}
5806
goto postaction;
5807
}
5808
}
5809
erroraction:
5810
USAGE_ERROR_ACTION(fm, p);
5811
postaction:
5812
POSTACTION(fm);
5813
}
5814
}
5815
}
5816
5817
void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
5818
void* mem;
5819
size_t req = 0;
5820
mstate ms = (mstate)msp;
5821
if (!ok_magic(ms)) {
5822
USAGE_ERROR_ACTION(ms,ms);
5823
return 0;
5824
}
5825
if (n_elements != 0) {
5826
req = n_elements * elem_size;
5827
if (((n_elements | elem_size) & ~(size_t)0xffff) &&
5828
(req / n_elements != elem_size))
5829
req = MAX_SIZE_T; /* force downstream failure on overflow */
5830
}
5831
mem = internal_malloc(ms, req);
5832
if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
5833
memset(mem, 0, req);
5834
return mem;
5835
}
5836
5837
void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
5838
void* mem = 0;
5839
if (oldmem == 0) {
5840
mem = mspace_malloc(msp, bytes);
5841
}
5842
else if (bytes >= MAX_REQUEST) {
5843
MALLOC_FAILURE_ACTION;
5844
}
5845
#ifdef REALLOC_ZERO_BYTES_FREES
5846
else if (bytes == 0) {
5847
mspace_free(msp, oldmem);
5848
}
5849
#endif /* REALLOC_ZERO_BYTES_FREES */
5850
else {
5851
size_t nb = request2size(bytes);
5852
mchunkptr oldp = mem2chunk(oldmem);
5853
#if ! FOOTERS
5854
mstate m = (mstate)msp;
5855
#else /* FOOTERS */
5856
mstate m = get_mstate_for(oldp);
5857
if (!ok_magic(m)) {
5858
USAGE_ERROR_ACTION(m, oldmem);
5859
return 0;
5860
}
5861
#endif /* FOOTERS */
5862
if (!PREACTION(m)) {
5863
mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
5864
POSTACTION(m);
5865
if (newp != 0) {
5866
check_inuse_chunk(m, newp);
5867
mem = chunk2mem(newp);
5868
}
5869
else {
5870
mem = mspace_malloc(m, bytes);
5871
if (mem != 0) {
5872
size_t oc = chunksize(oldp) - overhead_for(oldp);
5873
memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
5874
mspace_free(m, oldmem);
5875
}
5876
}
5877
}
5878
}
5879
return mem;
5880
}
5881
5882
void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {
5883
void* mem = 0;
5884
if (oldmem != 0) {
5885
if (bytes >= MAX_REQUEST) {
5886
MALLOC_FAILURE_ACTION;
5887
}
5888
else {
5889
size_t nb = request2size(bytes);
5890
mchunkptr oldp = mem2chunk(oldmem);
5891
#if ! FOOTERS
5892
mstate m = (mstate)msp;
5893
#else /* FOOTERS */
5894
mstate m = get_mstate_for(oldp);
5895
(void)msp; /* placate people compiling -Wunused */
5896
if (!ok_magic(m)) {
5897
USAGE_ERROR_ACTION(m, oldmem);
5898
return 0;
5899
}
5900
#endif /* FOOTERS */
5901
if (!PREACTION(m)) {
5902
mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
5903
POSTACTION(m);
5904
if (newp == oldp) {
5905
check_inuse_chunk(m, newp);
5906
mem = oldmem;
5907
}
5908
}
5909
}
5910
}
5911
return mem;
5912
}
5913
5914
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
5915
mstate ms = (mstate)msp;
5916
if (!ok_magic(ms)) {
5917
USAGE_ERROR_ACTION(ms,ms);
5918
return 0;
5919
}
5920
if (alignment <= MALLOC_ALIGNMENT)
5921
return mspace_malloc(msp, bytes);
5922
return internal_memalign(ms, alignment, bytes);
5923
}
5924
5925
void** mspace_independent_calloc(mspace msp, size_t n_elements,
5926
size_t elem_size, void* chunks[]) {
5927
size_t sz = elem_size; /* serves as 1-element array */
5928
mstate ms = (mstate)msp;
5929
if (!ok_magic(ms)) {
5930
USAGE_ERROR_ACTION(ms,ms);
5931
return 0;
5932
}
5933
return ialloc(ms, n_elements, &sz, 3, chunks);
5934
}
5935
5936
void** mspace_independent_comalloc(mspace msp, size_t n_elements,
5937
size_t sizes[], void* chunks[]) {
5938
mstate ms = (mstate)msp;
5939
if (!ok_magic(ms)) {
5940
USAGE_ERROR_ACTION(ms,ms);
5941
return 0;
5942
}
5943
return ialloc(ms, n_elements, sizes, 0, chunks);
5944
}
5945
5946
size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {
5947
return internal_bulk_free((mstate)msp, array, nelem);
5948
}
5949
5950
#if MALLOC_INSPECT_ALL
5951
void mspace_inspect_all(mspace msp,
5952
void(*handler)(void *start,
5953
void *end,
5954
size_t used_bytes,
5955
void* callback_arg),
5956
void* arg) {
5957
mstate ms = (mstate)msp;
5958
if (ok_magic(ms)) {
5959
if (!PREACTION(ms)) {
5960
internal_inspect_all(ms, handler, arg);
5961
POSTACTION(ms);
5962
}
5963
}
5964
else {
5965
USAGE_ERROR_ACTION(ms,ms);
5966
}
5967
}
5968
#endif /* MALLOC_INSPECT_ALL */
5969
5970
int mspace_trim(mspace msp, size_t pad) {
5971
int result = 0;
5972
mstate ms = (mstate)msp;
5973
if (ok_magic(ms)) {
5974
if (!PREACTION(ms)) {
5975
result = sys_trim(ms, pad);
5976
POSTACTION(ms);
5977
}
5978
}
5979
else {
5980
USAGE_ERROR_ACTION(ms,ms);
5981
}
5982
return result;
5983
}
5984
5985
#if !NO_MALLOC_STATS
5986
void mspace_malloc_stats(mspace msp) {
5987
mstate ms = (mstate)msp;
5988
if (ok_magic(ms)) {
5989
internal_malloc_stats(ms);
5990
}
5991
else {
5992
USAGE_ERROR_ACTION(ms,ms);
5993
}
5994
}
5995
#endif /* NO_MALLOC_STATS */
5996
5997
size_t mspace_footprint(mspace msp) {
5998
size_t result = 0;
5999
mstate ms = (mstate)msp;
6000
if (ok_magic(ms)) {
6001
result = ms->footprint;
6002
}
6003
else {
6004
USAGE_ERROR_ACTION(ms,ms);
6005
}
6006
return result;
6007
}
6008
6009
size_t mspace_max_footprint(mspace msp) {
6010
size_t result = 0;
6011
mstate ms = (mstate)msp;
6012
if (ok_magic(ms)) {
6013
result = ms->max_footprint;
6014
}
6015
else {
6016
USAGE_ERROR_ACTION(ms,ms);
6017
}
6018
return result;
6019
}
6020
6021
size_t mspace_footprint_limit(mspace msp) {
6022
size_t result = 0;
6023
mstate ms = (mstate)msp;
6024
if (ok_magic(ms)) {
6025
size_t maf = ms->footprint_limit;
6026
result = (maf == 0) ? MAX_SIZE_T : maf;
6027
}
6028
else {
6029
USAGE_ERROR_ACTION(ms,ms);
6030
}
6031
return result;
6032
}
6033
6034
size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {
6035
size_t result = 0;
6036
mstate ms = (mstate)msp;
6037
if (ok_magic(ms)) {
6038
if (bytes == 0)
6039
result = granularity_align(1); /* Use minimal size */
6040
if (bytes == MAX_SIZE_T)
6041
result = 0; /* disable */
6042
else
6043
result = granularity_align(bytes);
6044
ms->footprint_limit = result;
6045
}
6046
else {
6047
USAGE_ERROR_ACTION(ms,ms);
6048
}
6049
return result;
6050
}
6051
6052
#if !NO_MALLINFO
6053
struct mallinfo mspace_mallinfo(mspace msp) {
6054
mstate ms = (mstate)msp;
6055
if (!ok_magic(ms)) {
6056
USAGE_ERROR_ACTION(ms,ms);
6057
}
6058
return internal_mallinfo(ms);
6059
}
6060
#endif /* NO_MALLINFO */
6061
6062
size_t mspace_usable_size(const void* mem) {
6063
if (mem != 0) {
6064
mchunkptr p = mem2chunk(mem);
6065
if (is_inuse(p))
6066
return chunksize(p) - overhead_for(p);
6067
}
6068
return 0;
6069
}
6070
6071
int mspace_mallopt(int param_number, int value) {
6072
return change_mparam(param_number, value);
6073
}
6074
6075
#endif /* MSPACES */
6076
6077
// Export malloc and free as duplicate names emscripten_builtin_malloc and
6078
// emscripten_builtin_free so that applications can replace malloc and free
6079
// in their code, and make those replacements refer to the original dlmalloc
6080
// and dlfree from this file.
6081
// This allows an easy mechanism for hooking into memory allocation.
6082
#if defined(__EMSCRIPTEN__) && !ONLY_MSPACES
6083
extern __typeof(malloc) emscripten_builtin_malloc __attribute__((alias("dlmalloc")));
6084
extern __typeof(realloc) emscripten_builtin_realloc __attribute__((alias("dlrealloc")));
6085
extern __typeof(calloc) emscripten_builtin_calloc __attribute__((alias("dlcalloc")));
6086
extern __typeof(free) emscripten_builtin_free __attribute__((alias("dlfree")));
6087
extern __typeof(memalign) emscripten_builtin_memalign __attribute__((alias("dlmemalign")));
6088
#endif
6089
6090
/* -------------------- Alternative MORECORE functions ------------------- */
6091
6092
/*
6093
Guidelines for creating a custom version of MORECORE:
6094
6095
* For best performance, MORECORE should allocate in multiples of pagesize.
6096
* MORECORE may allocate more memory than requested. (Or even less,
6097
but this will usually result in a malloc failure.)
6098
* MORECORE must not allocate memory when given argument zero, but
6099
instead return one past the end address of memory from previous
6100
nonzero call.
6101
* For best performance, consecutive calls to MORECORE with positive
6102
arguments should return increasing addresses, indicating that
6103
space has been contiguously extended.
6104
* Even though consecutive calls to MORECORE need not return contiguous
6105
addresses, it must be OK for malloc'ed chunks to span multiple
6106
regions in those cases where they do happen to be contiguous.
6107
* MORECORE need not handle negative arguments -- it may instead
6108
just return MFAIL when given negative arguments.
6109
Negative arguments are always multiples of pagesize. MORECORE
6110
must not misinterpret negative args as large positive unsigned
6111
args unless UNSIGNED_MORECORE is defined. You can suppress all such calls
6112
from even occurring by defining MORECORE_CANNOT_TRIM,
6113
6114
As an example alternative MORECORE, here is a custom allocator
6115
kindly contributed for pre-OSX macOS. It uses virtually but not
6116
necessarily physically contiguous non-paged memory (locked in,
6117
present and won't get swapped out). You can use it by uncommenting
6118
this section, adding some #includes, and setting up the appropriate
6119
defines above:
6120
6121
#define MORECORE osMoreCore
6122
6123
There is also a shutdown routine that should somehow be called for
6124
cleanup upon program exit.
6125
6126
#define MAX_POOL_ENTRIES 100
6127
#define MINIMUM_MORECORE_SIZE (64 * 1024U)
6128
static int next_os_pool;
6129
void *our_os_pools[MAX_POOL_ENTRIES];
6130
6131
void *osMoreCore(int size)
6132
{
6133
void *ptr = 0;
6134
static void *sbrk_top = 0;
6135
6136
if (size > 0)
6137
{
6138
if (size < MINIMUM_MORECORE_SIZE)
6139
size = MINIMUM_MORECORE_SIZE;
6140
if (CurrentExecutionLevel() == kTaskLevel)
6141
ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
6142
if (ptr == 0)
6143
{
6144
return (void *) MFAIL;
6145
}
6146
// save ptrs so they can be freed during cleanup
6147
our_os_pools[next_os_pool] = ptr;
6148
next_os_pool++;
6149
ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
6150
sbrk_top = (char *) ptr + size;
6151
return ptr;
6152
}
6153
else if (size < 0)
6154
{
6155
// we don't currently support shrink behavior
6156
return (void *) MFAIL;
6157
}
6158
else
6159
{
6160
return sbrk_top;
6161
}
6162
}
6163
6164
// cleanup any allocated memory pools
6165
// called as last thing before shutting down driver
6166
6167
void osCleanupMem(void)
6168
{
6169
void **ptr;
6170
6171
for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
6172
if (*ptr)
6173
{
6174
PoolDeallocate(*ptr);
6175
*ptr = 0;
6176
}
6177
}
6178
6179
*/
6180
6181
6182
/* -----------------------------------------------------------------------
6183
History:
6184
v2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea
6185
* fix bad comparison in dlposix_memalign
6186
* don't reuse adjusted asize in sys_alloc
6187
* add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion
6188
* reduce compiler warnings -- thanks to all who reported/suggested these
6189
6190
v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee)
6191
* Always perform unlink checks unless INSECURE
6192
* Add posix_memalign.
6193
* Improve realloc to expand in more cases; expose realloc_in_place.
6194
Thanks to Peter Buhr for the suggestion.
6195
* Add footprint_limit, inspect_all, bulk_free. Thanks
6196
to Barry Hayes and others for the suggestions.
6197
* Internal refactorings to avoid calls while holding locks
6198
* Use non-reentrant locks by default. Thanks to Roland McGrath
6199
for the suggestion.
6200
* Small fixes to mspace_destroy, reset_on_error.
6201
* Various configuration extensions/changes. Thanks
6202
to all who contributed these.
6203
6204
V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu)
6205
* Update Creative Commons URL
6206
6207
V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee)
6208
* Use zeros instead of prev foot for is_mmapped
6209
* Add mspace_track_large_chunks; thanks to Jean Brouwers
6210
* Fix set_inuse in internal_realloc; thanks to Jean Brouwers
6211
* Fix insufficient sys_alloc padding when using 16byte alignment
6212
* Fix bad error check in mspace_footprint
6213
* Adaptations for ptmalloc; thanks to Wolfram Gloger.
6214
* Reentrant spin locks; thanks to Earl Chew and others
6215
* Win32 improvements; thanks to Niall Douglas and Earl Chew
6216
* Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options
6217
* Extension hook in malloc_state
6218
* Various small adjustments to reduce warnings on some compilers
6219
* Various configuration extensions/changes for more platforms. Thanks
6220
to all who contributed these.
6221
6222
V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee)
6223
* Add max_footprint functions
6224
* Ensure all appropriate literals are size_t
6225
* Fix conditional compilation problem for some #define settings
6226
* Avoid concatenating segments with the one provided
6227
in create_mspace_with_base
6228
* Rename some variables to avoid compiler shadowing warnings
6229
* Use explicit lock initialization.
6230
* Better handling of sbrk interference.
6231
* Simplify and fix segment insertion, trimming and mspace_destroy
6232
* Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
6233
* Thanks especially to Dennis Flanagan for help on these.
6234
6235
V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee)
6236
* Fix memalign brace error.
6237
6238
V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee)
6239
* Fix improper #endif nesting in C++
6240
* Add explicit casts needed for C++
6241
6242
V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee)
6243
* Use trees for large bins
6244
* Support mspaces
6245
* Use segments to unify sbrk-based and mmap-based system allocation,
6246
removing need for emulation on most platforms without sbrk.
6247
* Default safety checks
6248
* Optional footer checks. Thanks to William Robertson for the idea.
6249
* Internal code refactoring
6250
* Incorporate suggestions and platform-specific changes.
6251
Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
6252
Aaron Bachmann, Emery Berger, and others.
6253
* Speed up non-fastbin processing enough to remove fastbins.
6254
* Remove useless cfree() to avoid conflicts with other apps.
6255
* Remove internal memcpy, memset. Compilers handle builtins better.
6256
* Remove some options that no one ever used and rename others.
6257
6258
V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
6259
* Fix malloc_state bitmap array misdeclaration
6260
6261
V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee)
6262
* Allow tuning of FIRST_SORTED_BIN_SIZE
6263
* Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
6264
* Better detection and support for non-contiguousness of MORECORE.
6265
Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
6266
* Bypass most of malloc if no frees. Thanks To Emery Berger.
6267
* Fix freeing of old top non-contiguous chunk im sysmalloc.
6268
* Raised default trim and map thresholds to 256K.
6269
* Fix mmap-related #defines. Thanks to Lubos Lunak.
6270
* Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
6271
* Branch-free bin calculation
6272
* Default trim and mmap thresholds now 256K.
6273
6274
V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee)
6275
* Introduce independent_comalloc and independent_calloc.
6276
Thanks to Michael Pachos for motivation and help.
6277
* Make optional .h file available
6278
* Allow > 2GB requests on 32bit systems.
6279
* new WIN32 sbrk, mmap, munmap, lock code from <[email protected]>.
6280
Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
6281
and Anonymous.
6282
* Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
6283
helping test this.)
6284
* memalign: check alignment arg
6285
* realloc: don't try to shift chunks backwards, since this
6286
leads to more fragmentation in some programs and doesn't
6287
seem to help in any others.
6288
* Collect all cases in malloc requiring system memory into sysmalloc
6289
* Use mmap as backup to sbrk
6290
* Place all internal state in malloc_state
6291
* Introduce fastbins (although similar to 2.5.1)
6292
* Many minor tunings and cosmetic improvements
6293
* Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
6294
* Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
6295
Thanks to Tony E. Bennett <[email protected]> and others.
6296
* Include errno.h to support default failure action.
6297
6298
V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee)
6299
* return null for negative arguments
6300
* Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
6301
* Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
6302
(e.g. WIN32 platforms)
6303
* Cleanup header file inclusion for WIN32 platforms
6304
* Cleanup code to avoid Microsoft Visual C++ compiler complaints
6305
* Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
6306
memory allocation routines
6307
* Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
6308
* Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
6309
usage of 'assert' in non-WIN32 code
6310
* Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
6311
avoid infinite loop
6312
* Always call 'fREe()' rather than 'free()'
6313
6314
V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee)
6315
* Fixed ordering problem with boundary-stamping
6316
6317
V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee)
6318
* Added pvalloc, as recommended by H.J. Liu
6319
* Added 64bit pointer support mainly from Wolfram Gloger
6320
* Added anonymously donated WIN32 sbrk emulation
6321
* Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
6322
* malloc_extend_top: fix mask error that caused wastage after
6323
foreign sbrks
6324
* Add linux mremap support code from HJ Liu
6325
6326
V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee)
6327
* Integrated most documentation with the code.
6328
* Add support for mmap, with help from
6329
Wolfram Gloger ([email protected]).
6330
* Use last_remainder in more cases.
6331
* Pack bins using idea from [email protected]
6332
* Use ordered bins instead of best-fit threshhold
6333
* Eliminate block-local decls to simplify tracing and debugging.
6334
* Support another case of realloc via move into top
6335
* Fix error occuring when initial sbrk_base not word-aligned.
6336
* Rely on page size for units instead of SBRK_UNIT to
6337
avoid surprises about sbrk alignment conventions.
6338
* Add mallinfo, mallopt. Thanks to Raymond Nijssen
6339
([email protected]) for the suggestion.
6340
* Add `pad' argument to malloc_trim and top_pad mallopt parameter.
6341
* More precautions for cases where other routines call sbrk,
6342
courtesy of Wolfram Gloger ([email protected]).
6343
* Added macros etc., allowing use in linux libc from
6344
H.J. Lu ([email protected])
6345
* Inverted this history list
6346
6347
V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee)
6348
* Re-tuned and fixed to behave more nicely with V2.6.0 changes.
6349
* Removed all preallocation code since under current scheme
6350
the work required to undo bad preallocations exceeds
6351
the work saved in good cases for most test programs.
6352
* No longer use return list or unconsolidated bins since
6353
no scheme using them consistently outperforms those that don't
6354
given above changes.
6355
* Use best fit for very large chunks to prevent some worst-cases.
6356
* Added some support for debugging
6357
6358
V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee)
6359
* Removed footers when chunks are in use. Thanks to
6360
Paul Wilson ([email protected]) for the suggestion.
6361
6362
V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee)
6363
* Added malloc_trim, with help from Wolfram Gloger
6364
([email protected]).
6365
6366
V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g)
6367
6368
V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g)
6369
* realloc: try to expand in both directions
6370
* malloc: swap order of clean-bin strategy;
6371
* realloc: only conditionally expand backwards
6372
* Try not to scavenge used bins
6373
* Use bin counts as a guide to preallocation
6374
* Occasionally bin return list chunks in first scan
6375
* Add a few optimizations from [email protected]
6376
6377
V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g)
6378
* faster bin computation & slightly different binning
6379
* merged all consolidations to one part of malloc proper
6380
(eliminating old malloc_find_space & malloc_clean_bin)
6381
* Scan 2 returns chunks (not just 1)
6382
* Propagate failure in realloc if malloc returns 0
6383
* Add stuff to allow compilation on non-ANSI compilers
6384
from [email protected]
6385
6386
V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu)
6387
* removed potential for odd address access in prev_chunk
6388
* removed dependency on getpagesize.h
6389
* misc cosmetics and a bit more internal documentation
6390
* anticosmetics: mangled names in macros to evade debugger strangeness
6391
* tested on sparc, hp-700, dec-mips, rs6000
6392
with gcc & native cc (hp, dec only) allowing
6393
Detlefs & Zorn comparison study (in SIGPLAN Notices.)
6394
6395
Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu)
6396
* Based loosely on libg++-1.2X malloc. (It retains some of the overall
6397
structure of old version, but most details differ.)
6398
6399
*/
6400
6401