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