16661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 26661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This is a version (aka dlmalloc) of malloc/free/realloc written by 36661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Doug Lea and released to the public domain, as explained at 46661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao http://creativecommons.org/publicdomain/zero/1.0/ Send questions, 56661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao comments, complaints, performance data, etc to dl@cs.oswego.edu 66661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 76661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao* Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea 86661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note: There may be an updated version of this malloc obtainable at 96661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ftp://gee.cs.oswego.edu/pub/misc/malloc.c 106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Check before installing! 116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao* Quickstart 136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This library is all in one file to simplify the most common usage: 156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ftp it, compile it (-O3), and link it into another program. All of 166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the compile-time options default to reasonable values for use on 176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao most platforms. You might later want to step through various 186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compile-time and dynamic tuning options. 196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao For convenience, an include file for code using this malloc is at: 216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h 226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao You don't really need this .h file unless you call functions not 236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao defined in your system include files. The .h file contains only the 246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao excerpts from this file needed for using this malloc on ANSI C/C++ 256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao systems, so long as you haven't changed compile-time options about 266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao naming and tuning parameters. If you do, then you can create your 276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao own malloc.h that does include all settings by cutting at the point 286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao indicated below. Note that you may already by default be using a C 296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao library containing a malloc that is based on some version of this 306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc (for example in linux). You might still want to use the one 316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in this file to customize settings or to avoid overheads associated 326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with library versions. 336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao* Vital statistics: 356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Supported pointer/size_t representation: 4 or 8 bytes 376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t MUST be an unsigned type of the same width as 386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointers. (If you are using an ancient system that declares 396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t as a signed type, or need it to be a different width 406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao than pointers, you can use a previous release of this malloc 416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (e.g. 2.7.2) supporting these.) 426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Alignment: 8 bytes (minimum) 446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This suffices for nearly all current machines and C compilers. 456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao However, you can define MALLOC_ALIGNMENT to be wider than this 466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if necessary (up to 128bytes), at the expense of using more space. 476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) 496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8 or 16 bytes (if 8byte sizes) 506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each malloced chunk has a hidden word of overhead holding size 516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and status information, and additional cross-check word 526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if FOOTERS is defined. 536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) 556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8-byte ptrs: 32 bytes (including overhead) 566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Even a request for zero bytes (i.e., malloc(0)) returns a 586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointer to something of the minimum allocatable size. 596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The maximum overhead wastage (i.e., number of extra bytes 606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocated than were requested in malloc) is less than or equal 616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to the minimum size, except for requests >= mmap_threshold that 626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are serviced via mmap(), where the worst case wastage is about 636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32 bytes plus the remainder from a system page (the minimal 646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mmap unit); typically 4096 or 8192 bytes. 656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Security: static-safe; optionally more or less 676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The "security" of malloc refers to the ability of malicious 686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao code to accentuate the effects of errors (for example, freeing 696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space that is not currently malloc'ed or overwriting past the 706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ends of chunks) in code that calls malloc. This malloc 716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao guarantees not to modify any memory locations below the base of 726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao heap, i.e., static variables, even in the presence of usage 736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao errors. The routines additionally detect most improper frees 746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and reallocs. All this holds as long as the static bookkeeping 756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for malloc itself is not corrupted by some other means. This 766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is only one aspect of security -- these checks do not, and 776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cannot, detect all possible programming errors. 786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If FOOTERS is defined nonzero, then each allocated chunk 806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao carries an additional check word to verify that it was malloced 816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao from its space. These check words are the same within each 826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao execution of a program using malloc, but differ across 836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao executions, so externally crafted fake chunks cannot be 846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao freed. This improves security by rejecting frees/reallocs that 856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao could corrupt heap memory, in addition to the checks preventing 866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao writes to statics that are always on. This may further improve 876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao security at the expense of time and space overhead. (Note that 886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao FOOTERS may also be worth using with MSPACES.) 896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao By default detected errors cause the program to abort (calling 916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao "abort()"). You can override this to instead proceed past 926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao errors by defining PROCEED_ON_ERROR. In this case, a bad free 936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao has no effect, and a malloc that encounters a bad address 946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao caused by user overwrites will ignore the bad address by 956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dropping pointers and indices to all known memory. This may 966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be appropriate for programs that should continue if at all 976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao possible in the face of programming errors, although they may 986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao run out of memory because dropped memory is never reclaimed. 996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If you don't like either of these options, you can define 1016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything 1026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else. And if if you are sure that your program using malloc has 1036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao no errors or vulnerabilities, you can define INSECURE to 1, 1046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao which might (or might not) provide a small performance improvement. 1056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao It is also possible to limit the maximum total allocatable 1076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space, using malloc_set_footprint_limit. This is not 1086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao designed as a security feature in itself (calls to set limits 1096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are not screened or privileged), but may be useful as one 1106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao aspect of a secure implementation. 1116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero 1136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao When USE_LOCKS is defined, each public call to malloc, free, 1146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao etc is surrounded with a lock. By default, this uses a plain 1156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pthread mutex, win32 critical section, or a spin-lock if if 1166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao available for the platform and not disabled by setting 1176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined, 1186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao recursive versions are used instead (which are not required for 1196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao base functionality but may be needed in layered extensions). 1206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Using a global lock is not especially fast, and can be a major 1216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bottleneck. It is designed only to provide minimal protection 1226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in concurrent environments, and to provide a basis for 1236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extensions. If you are using malloc in a concurrent program, 1246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao consider instead using nedmalloc 1256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (http://www.nedprod.com/programs/portable/nedmalloc/) or 1266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ptmalloc (See http://www.malloc.de), which are derived from 1276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao versions of this malloc. 1286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao System requirements: Any combination of MORECORE and/or MMAP/MUNMAP 1306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This malloc can use unix sbrk or any emulation (invoked using 1316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the CALL_MORECORE macro) and/or mmap/munmap or any emulation 1326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system 1336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory. On most unix systems, it tends to work best if both 1346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MORECORE and MMAP are enabled. On Win32, it uses emulations 1356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao based on VirtualAlloc. It also uses common C library functions 1366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao like memset. 1376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Compliance: I believe it is compliant with the Single Unix Specification 1396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably 1406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao others as well. 1416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao* Overview of algorithms 1436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This is not the fastest, most space-conserving, most portable, or 1456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao most tunable malloc ever written. However it is among the fastest 1466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while also being among the most space-conserving, portable and 1476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tunable. Consistent balance across these factors results in a good 1486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao general-purpose allocator for malloc-intensive programs. 1496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao In most ways, this malloc is a best-fit allocator. Generally, it 1516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chooses the best-fitting existing chunk for a request, with ties 1526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao broken in approximately least-recently-used order. (This strategy 1536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao normally maintains low fragmentation.) However, for requests less 1546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao than 256bytes, it deviates from best-fit when there is not an 1556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao exactly fitting available chunk by preferring to use space adjacent 1566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to that used for the previous small request, as well as by breaking 1576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ties in approximately most-recently-used order. (These enhance 1586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao locality of series of small allocations.) And for very large requests 1596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (>= 256Kb by default), it relies on system memory mapping 1606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao facilities, if supported. (This helps avoid carrying around and 1616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao possibly fragmenting memory used only for large chunks.) 1626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao All operations (except malloc_stats and mallinfo) have execution 1646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao times that are bounded by a constant factor of the number of bits in 1656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao a size_t, not counting any clearing in calloc or copying in realloc, 1666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao or actions surrounding MORECORE and MMAP that have times 1676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao proportional to the number of non-contiguous regions returned by 1686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system allocation routines, which is often just 1. In real-time 1696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao applications, you can optionally suppress segment traversals using 1706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao NO_SEGMENT_TRAVERSAL, which assures bounded execution even when 1716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system allocators return non-contiguous spaces, at the typical 1726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao expense of carrying around more memory and increased fragmentation. 1736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The implementation is not very modular and seriously overuses 1756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao macros. Perhaps someday all C compilers will do as good a job 1766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao inlining modular code as can now be done by brute-force expansion, 1776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao but now, enough of them seem not to. 1786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Some compilers issue a lot of warnings about code that is 1806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dead/unreachable only on some platforms, and also about intentional 1816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao uses of negation on unsigned types. All known cases of each can be 1826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ignored. 1836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao For a longer but out of date high-level description, see 1856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao http://gee.cs.oswego.edu/dl/html/malloc.html 1866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao* MSPACES 1886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If MSPACES is defined, then in addition to malloc, free, etc., 1896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this file also defines mspace_malloc, mspace_free, etc. These 1906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are versions of malloc routines that take an "mspace" argument 1916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao obtained using create_mspace, to control all internal bookkeeping. 1926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If ONLY_MSPACES is defined, only these versions are compiled. 1936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao So if you would like to use this allocator for only some allocations, 1946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and your system malloc for others, you can compile with 1956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ONLY_MSPACES and then do something like... 1966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static mspace mymspace = create_mspace(0,0); // for example 1976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define mymalloc(bytes) mspace_malloc(mymspace, bytes) 1986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (Note: If you only need one instance of an mspace, you can instead 2006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao use "USE_DL_PREFIX" to relabel the global malloc.) 2016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao You can similarly create thread-local allocators by storing 2036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspaces as thread-locals. For example: 2046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static __thread mspace tlms = 0; 2056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* tlmalloc(size_t bytes) { 2066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (tlms == 0) tlms = create_mspace(0, 0); 2076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mspace_malloc(tlms, bytes); 2086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 2096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void tlfree(void* mem) { mspace_free(tlms, mem); } 2106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Unless FOOTERS is defined, each mspace is completely independent. 2126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao You cannot allocate from one and free to another (although 2136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao conformance is only weakly checked, so usage errors are not always 2146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao caught). If FOOTERS is defined, then each chunk carries around a tag 2156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao indicating its originating mspace, and frees are directed to their 2166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao originating spaces. Normally, this requires use of locks. 2176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ------------------------- Compile-time options --------------------------- 2196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoBe careful in setting #define values for numerical constants of type 2216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t. On some systems, literal values are not automatically extended 2226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoto size_t precision unless they are explicitly casted. You can also 2236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaouse the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. 2246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoWIN32 default: defined if _WIN32 defined 2266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Defining WIN32 sets up defaults for MS environment and compilers. 2276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Otherwise defaults are for unix. Beware that there seem to be some 2286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cases where this malloc might not be a pure drop-in replacement for 2296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Win32 malloc: Random-looking failures from Win32 GDI API's (eg; 2306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SetDIBits()) may be due to bugs in some video driver implementations 2316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao when pixel buffers are malloc()ed, and the region spans more than 2326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) 2336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao default granularity, pixel buffers may straddle virtual allocation 2346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao regions more often than when using the Microsoft allocator. You can 2356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao avoid this by using VirtualAlloc() and VirtualFree() for all pixel 2366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao buffers rather than using malloc(). If this is not possible, 2376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao recompile this malloc with a larger DEFAULT_GRANULARITY. Note: 2386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in cases where MSC and gcc (cygwin) are known to differ on WIN32, 2396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao conditions use _MSC_VER to distinguish them. 2406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT default: extern 2426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Defines how public APIs are declared. If you want to export via a 2436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Windows DLL, you might define this as 2446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define DLMALLOC_EXPORT extern __declspec(dllexport) 2456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If you want a POSIX ELF shared object, you might use 2466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define DLMALLOC_EXPORT extern __attribute__((visibility("default"))) 2476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMALLOC_ALIGNMENT default: (size_t)(2 * sizeof(void *)) 2496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Controls the minimum alignment for malloc'ed chunks. It must be a 2506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao power of two and at least 8, even on machines for which smaller 2516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignments would suffice. It may be defined as larger than this 2526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao though. Note however that code and data structures are optimized for 2536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the case of 8-byte alignment. 2546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMSPACES default: 0 (false) 2566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, compile in support for independent allocation spaces. 2576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This is only supported if HAVE_MMAP is true. 2586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoONLY_MSPACES default: 0 (false) 2606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, only compile in mspace versions, not regular versions. 2616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_LOCKS default: 0 (false) 2636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Causes each call to each public routine to be surrounded with 2646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pthread or WIN32 mutex lock/unlock. (If set true, this can be 2656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao overridden on a per-mspace basis for mspace versions.) If set to a 2666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao non-zero value other than 1, locks are used, but their 2676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao implementation is left out, so lock functions must be supplied manually, 2686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao as described below. 2696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available 2716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, uses custom spin locks for locking. This is currently 2726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao supported only gcc >= 4.1, older gccs on x86 platforms, and recent 2736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MS compilers. Otherwise, posix locks or win32 critical sections are 2746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used. 2756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_RECURSIVE_LOCKS default: not defined 2776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If defined nonzero, uses recursive (aka reentrant) locks, otherwise 2786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao uses plain mutexes. This is not required for malloc proper, but may 2796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be needed for layered allocators such as nedmalloc. 2806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLOCK_AT_FORK default: not defined 2826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If defined nonzero, performs pthread_atfork upon initialization 2836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to initialize child lock while holding parent lock. The implementation 2846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assumes that pthread locks (not custom locks) are being used. In other 2856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cases, you may need to customize the implementation. 2866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoFOOTERS default: 0 2886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, provide extra checking and dispatching by placing 2896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao information in the footers of allocated chunks. This adds 2906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space and time overhead. 2916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoINSECURE default: 0 2936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, omit checks for usage errors and heap space overwrites. 2946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_DL_PREFIX default: NOT defined 2966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Causes compiler to prefix all public routines with the string 'dl'. 2976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This can be useful when you only want to use this malloc in one part 2986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of a program, using your regular system malloc elsewhere. 2996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMALLOC_INSPECT_ALL default: NOT defined 3016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If defined, compiles malloc_inspect_all and mspace_inspect_all, that 3026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao perform traversal of all heap space. Unless access to these 3036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao functions is otherwise restricted, you probably do not want to 3046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao include them in secure implementations. 3056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoABORT default: defined as abort() 3076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Defines how to abort on failed checks. On most systems, a failed 3086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check cannot die with an "assert" or even print an informative 3096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao message, because the underlying print routines in turn call malloc, 3106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao which will fail again. Generally, the best policy is to simply call 3116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao abort(). It's not very useful to do more than this because many 3126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao errors due to overwriting will show up as address faults (null, odd 3136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao addresses etc) rather than malloc-triggered checks, so will also 3146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao abort. Also, most compilers know that abort() does not return, so 3156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao can better optimize code conditionally calling it. 3166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoPROCEED_ON_ERROR default: defined as 0 (false) 3186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Controls whether detected bad addresses cause them to bypassed 3196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rather than aborting. If set, detected bad arguments to free and 3206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc are ignored. And all bookkeeping information is zeroed out 3216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao upon a detected overwrite of freed heap space, thus losing the 3226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ability to ever return it from malloc again, but enabling the 3236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao application to proceed. If PROCEED_ON_ERROR is defined, the 3246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static variable malloc_corruption_error_count is compiled in 3256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and can be examined to see if errors have occurred. This option 3266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao generates slower code than the default abort policy. 3276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDEBUG default: NOT defined 3296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The DEBUG setting is mainly intended for people trying to modify 3306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this code or diagnose problems when porting to new platforms. 3316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao However, it may also be able to better isolate user errors than just 3326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao using runtime checks. The assertions in the check routines spell 3336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao out in more detail the assumptions and invariants underlying the 3346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao algorithms. The checking is fairly extensive, and will slow down 3356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao execution noticeably. Calling malloc_stats or mallinfo with DEBUG 3366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set will attempt to check every non-mmapped allocated and free chunk 3376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in the course of computing the summaries. 3386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoABORT_ON_ASSERT_FAILURE default: defined as 1 (true) 3406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Debugging assertion failures can be nearly impossible if your 3416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao version of the assert macro causes malloc to be called, which will 3426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lead to a cascade of further failures, blowing the runtime stack. 3436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), 3446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao which will usually make debugging easier. 3456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 3476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The action to take before "return 0" when malloc fails to be able to 3486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return memory because there is none available. 3496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoHAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES 3516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao True if this system supports sbrk or an emulation of it. 3526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMORECORE default: sbrk 3546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The name of the sbrk-style system routine to call to obtain more 3556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory. See below for guidance on writing custom MORECORE 3566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao functions. The type of the argument to sbrk/MORECORE varies across 3576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao systems. It cannot be size_t, because it supports negative 3586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao arguments, so it is normally the signed type of the same width as 3596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t (sometimes declared as "intptr_t"). It doesn't much matter 3606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao though. Internally, we only call it with arguments less than half 3616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the max value of a size_t, which should work across all reasonable 3626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao possibilities, although sometimes generating compiler warnings. 3636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE 3656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true, take advantage of fact that consecutive calls to MORECORE 3666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with positive arguments always return contiguous increasing 3676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao addresses. This is true of unix sbrk. It does not hurt too much to 3686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set it true anyway, since malloc copes with non-contiguities. 3696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Setting it false when definitely non-contiguous saves time 3706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and possibly wasted space it would take to discover this though. 3716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMORECORE_CANNOT_TRIM default: NOT defined 3736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao True if MORECORE cannot release space back to the system when given 3746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao negative arguments. This is generally necessary only if you are 3756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao using a hand-crafted MORECORE function that cannot handle negative 3766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao arguments. 3776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoNO_SEGMENT_TRAVERSAL default: 0 3796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If non-zero, suppresses traversals of memory segments 3806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao returned by either MORECORE or CALL_MMAP. This disables 3816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao merging of segments that are contiguous, and selectively 3826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao releasing them to the OS if unused, but bounds execution times. 3836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoHAVE_MMAP default: 1 (true) 3856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao True if this system supports mmap or an emulation of it. If so, and 3866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao HAVE_MORECORE is not true, MMAP is used for all system 3876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocation. If set and HAVE_MORECORE is true as well, MMAP is 3886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao primarily used to directly allocate very large blocks. It is also 3896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used as a backup strategy in cases where MORECORE fails to provide 3906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space from system. Note: A single call to MUNMAP is assumed to be 3916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao able to unmap memory that may have be allocated using multiple calls 3926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to MMAP, so long as they are adjacent. 3936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoHAVE_MREMAP default: 1 on linux, else 0 3956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If true realloc() uses mremap() to re-allocate large blocks and 3966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extend or shrink allocation spaces. 3976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMMAP_CLEARS default: 1 except on WINCE. 3996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao True if mmap clears memory so calloc doesn't need to. This is true 4006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for standard unix mmap using /dev/zero and on WIN32 except for WINCE. 4016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_BUILTIN_FFS default: 0 (i.e., not used) 4036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Causes malloc to use the builtin ffs() function to compute indices. 4046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Some compilers may recognize and intrinsify ffs to be faster than the 4056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao supplied C version. Also, the case of x86 using gcc is special-cased 4066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to an asm instruction, so is already as fast as it can be, and so 4076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this setting has no effect. Similarly for Win32 under recent MS compilers. 4086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (On most x86s, the asm version is only slightly faster than the C version.) 4096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaomalloc_getpagesize default: derive from system includes, or 4096. 4116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The system page size. To the extent possible, this malloc manages 4126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory from the system in page-size units. This may be (and 4136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao usually is) a function rather than a constant. This is ignored 4146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if WIN32, where page size is determined using getSystemInfo during 4156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao initialization. 4166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoUSE_DEV_RANDOM default: 0 (i.e., not used) 4186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Causes malloc to use /dev/random to initialize secure magic seed for 4196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao stamping footers. Otherwise, the current time is used. 4206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoNO_MALLINFO default: 0 4226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If defined, don't compile "mallinfo". This can be a simple way 4236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of dealing with mismatches between system declarations and 4246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao those in this file. 4256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMALLINFO_FIELD_TYPE default: size_t 4276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The type of the fields in the mallinfo struct. This was originally 4286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao defined as "int" in SVID etc, but is more usefully defined as 4296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set 4306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoNO_MALLOC_STATS default: 0 4326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If defined, don't compile "malloc_stats". This avoids calls to 4336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fprintf and bringing in stdio dependencies you might not want. 4346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoREALLOC_ZERO_BYTES_FREES default: not defined 4366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This should be set if a call to realloc with zero bytes should 4376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be the same as a call to free. Some people think it should. Otherwise, 4386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao since this malloc returns a unique pointer for malloc(0), so does 4396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc(p, 0). 4406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H 4426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H 4436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32 4446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Define these if your system does not have these header files. 4456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao You might need to manually insert some of the declarations they provide. 4466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, 4486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system_info.dwAllocationGranularity in WIN32, 4496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao otherwise 64K. 4506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Also settable using mallopt(M_GRANULARITY, x) 4516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The unit for allocating and deallocating memory from the system. On 4526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao most systems with contiguous MORECORE, there is no reason to 4536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao make this more than a page. However, systems with MMAP tend to 4546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao either require or encourage larger granularities. You can increase 4556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this value to prevent system allocation functions to be called so 4566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao often, especially if they are slow. The value must be at least one 4576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao page and must be a power of two. Setting to 0 causes initialization 4586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to either page size or win32 region size. (Note: In previous 4596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao versions of malloc, the equivalent of this option was called 4606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao "TOP_PAD") 4616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDEFAULT_TRIM_THRESHOLD default: 2MB 4636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Also settable using mallopt(M_TRIM_THRESHOLD, x) 4646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The maximum amount of unused top-most memory to keep before 4656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao releasing via malloc_trim in free(). Automatic trimming is mainly 4666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao useful in long-lived programs using contiguous MORECORE. Because 4676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao trimming via sbrk can be slow on some systems, and can sometimes be 4686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao wasteful (in cases where programs immediately afterward allocate 4696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao more large chunks) the value should be high enough so that your 4706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao overall system performance would improve by releasing this much 4716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory. As a rough guide, you might set to a value close to the 4726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao average size of a process (program) running on your system. 4736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Releasing this much memory would allow such a process to run in 4746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory. Generally, it is worth tuning trim thresholds when a 4756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao program undergoes phases where several large chunks are allocated 4766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and released in ways that can reuse each other's storage, perhaps 4776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mixed with phases where there are no such chunks at all. The trim 4786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao value must be greater than page size to have any useful effect. To 4796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable trimming completely, you can set to MAX_SIZE_T. Note that the trick 4806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao some people use of mallocing a huge space and then freeing it at 4816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao program startup, in an attempt to reserve system memory, doesn't 4826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao have the intended effect under automatic trimming, since that memory 4836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao will immediately be returned to the system. 4846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDEFAULT_MMAP_THRESHOLD default: 256K 4866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Also settable using mallopt(M_MMAP_THRESHOLD, x) 4876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The request size threshold for using MMAP to directly service a 4886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao request. Requests of at least this size that cannot be allocated 4896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao using already-existing space will be serviced via mmap. (If enough 4906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao normal freed space already exists it is used instead.) Using mmap 4916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao segregates relatively large chunks of memory so that they can be 4926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao individually obtained and released from the host system. A request 4936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao serviced through mmap is never reused by any other request (at least 4946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao not directly; the system may just so happen to remap successive 4956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao requests to the same locations). Segregating space in this way has 4966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the benefits that: Mmapped space can always be individually released 4976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao back to the system, which helps keep the system level memory demands 4986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of a long-lived program low. Also, mapped memory doesn't become 4996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao `locked' between other chunks, as can happen with normally allocated 5006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks, which means that even trimming via malloc_trim would not 5016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao release them. However, it has the disadvantage that the space 5026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cannot be reclaimed, consolidated, and then used to service later 5036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao requests, as happens with normal chunks. The advantages of mmap 5046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nearly always outweigh disadvantages for "large" chunks, but the 5056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao value of "large" may vary across systems. The default is an 5066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao empirically derived value that works well in most systems. You can 5076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable mmap by setting to MAX_SIZE_T. 5086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoMAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP 5106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The number of consolidated frees between checks to release 5116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unused segments when freeing. When using non-contiguous segments, 5126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao especially with multiple mspaces, checking only for topmost space 5136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao doesn't always suffice to trigger trimming. To compensate for this, 5146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free() will, with a period of MAX_RELEASE_CHECK_RATE (or the 5156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao current number of segments, if greater) try to release unused 5166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao segments to the OS when freeing chunks that result in 5176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao consolidation. The best value for this parameter is a compromise 5186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao between slowing down frees with relatively costly checks that 5196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rarely trigger versus holding on to unused memory. To effectively 5206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable, set to MAX_SIZE_T. This may lead to a very slight speed 5216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao improvement at the expense of carrying around more memory. 5226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 5236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Version identifier to allow people to support multiple versions */ 5256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef DLMALLOC_VERSION 5266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DLMALLOC_VERSION 20806 5276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DLMALLOC_VERSION */ 5286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef DLMALLOC_EXPORT 5306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DLMALLOC_EXPORT extern 5316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 5326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 5346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef _WIN32 5356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define WIN32 1 5366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* _WIN32 */ 5376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef _WIN32_WCE 5386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_FCNTL_H 5396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define WIN32 1 5406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* _WIN32_WCE */ 5416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 5426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef WIN32 5436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define WIN32_LEAN_AND_MEAN 5446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <windows.h> 5456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <tchar.h> 5466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MMAP 1 5476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MORECORE 0 5486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_UNISTD_H 5496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_SYS_PARAM_H 5506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_SYS_MMAN_H 5516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_STRING_H 5526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_STRINGS_H 5536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_SYS_TYPES_H 5546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_ERRNO_H 5556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LACKS_SCHED_H 5566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLOC_FAILURE_ACTION 5576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLOC_FAILURE_ACTION 5586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_FAILURE_ACTION */ 5596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MMAP_CLEARS 5606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ 5616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_CLEARS 0 5626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 5636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_CLEARS 1 5646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* _WIN32_WCE */ 5656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /*MMAP_CLEARS */ 5666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 5676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(DARWIN) || defined(_DARWIN) 5696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ 5706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef HAVE_MORECORE 5716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MORECORE 0 5726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MMAP 1 5736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* OSX allocators provide 16 byte alignment */ 5746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLOC_ALIGNMENT 5756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLOC_ALIGNMENT ((size_t)16U) 5766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 5776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MORECORE */ 5786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DARWIN */ 5796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_SYS_TYPES_H 5816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <sys/types.h> /* For size_t */ 5826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_SYS_TYPES_H */ 5836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The maximum possible size_t value has all bits set */ 5856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_SIZE_T (~(size_t)0) 5866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */ 5886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \ 5896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)) 5906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 5916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */ 5936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ((defined(__GNUC__) && \ 5946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \ 5956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao defined(__i386__) || defined(__x86_64__))) || \ 5966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (defined(_MSC_VER) && _MSC_VER>=1310)) 5976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USE_SPIN_LOCKS 5986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_SPIN_LOCKS 1 5996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_SPIN_LOCKS */ 6006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif USE_SPIN_LOCKS 6016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#error "USE_SPIN_LOCKS defined without implementation" 6026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ... locks available... */ 6036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif !defined(USE_SPIN_LOCKS) 6046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_SPIN_LOCKS 0 6056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 6066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 6076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef ONLY_MSPACES 6086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ONLY_MSPACES 0 6096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ONLY_MSPACES */ 6106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MSPACES 6116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ONLY_MSPACES 6126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MSPACES 1 6136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* ONLY_MSPACES */ 6146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MSPACES 0 6156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ONLY_MSPACES */ 6166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MSPACES */ 6176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLOC_ALIGNMENT 6186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *))) 6196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_ALIGNMENT */ 6206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef FOOTERS 6216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FOOTERS 0 6226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 6236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef ABORT 6246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ABORT abort() 6256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ABORT */ 6266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef ABORT_ON_ASSERT_FAILURE 6276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ABORT_ON_ASSERT_FAILURE 1 6286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ABORT_ON_ASSERT_FAILURE */ 6296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef PROCEED_ON_ERROR 6306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define PROCEED_ON_ERROR 0 6316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* PROCEED_ON_ERROR */ 6326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 6336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef INSECURE 6346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INSECURE 0 6356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* INSECURE */ 6366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLOC_INSPECT_ALL 6376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLOC_INSPECT_ALL 0 6386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_INSPECT_ALL */ 6396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef HAVE_MMAP 6406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MMAP 1 6416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 6426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MMAP_CLEARS 6436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_CLEARS 1 6446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MMAP_CLEARS */ 6456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef HAVE_MREMAP 6466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef linux 6476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MREMAP 1 6486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define _GNU_SOURCE /* Turns on mremap() definition */ 6496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* linux */ 6506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MREMAP 0 6516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* linux */ 6526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MREMAP */ 6536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLOC_FAILURE_ACTION 6546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLOC_FAILURE_ACTION errno = ENOMEM; 6556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_FAILURE_ACTION */ 6566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef HAVE_MORECORE 6576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ONLY_MSPACES 6586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MORECORE 0 6596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* ONLY_MSPACES */ 6606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HAVE_MORECORE 1 6616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ONLY_MSPACES */ 6626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MORECORE */ 6636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !HAVE_MORECORE 6646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MORECORE_CONTIGUOUS 0 6656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* !HAVE_MORECORE */ 6666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MORECORE_DEFAULT sbrk 6676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MORECORE_CONTIGUOUS 6686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MORECORE_CONTIGUOUS 1 6696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MORECORE_CONTIGUOUS */ 6706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MORECORE */ 6716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef DEFAULT_GRANULARITY 6726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if (MORECORE_CONTIGUOUS || defined(WIN32)) 6736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ 6746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MORECORE_CONTIGUOUS */ 6756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) 6766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MORECORE_CONTIGUOUS */ 6776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEFAULT_GRANULARITY */ 6786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef DEFAULT_TRIM_THRESHOLD 6796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MORECORE_CANNOT_TRIM 6806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) 6816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MORECORE_CANNOT_TRIM */ 6826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T 6836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MORECORE_CANNOT_TRIM */ 6846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEFAULT_TRIM_THRESHOLD */ 6856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef DEFAULT_MMAP_THRESHOLD 6866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 6876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) 6886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* HAVE_MMAP */ 6896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T 6906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 6916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEFAULT_MMAP_THRESHOLD */ 6926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MAX_RELEASE_CHECK_RATE 6936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 6946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_RELEASE_CHECK_RATE 4095 6956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 6966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T 6976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 6986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MAX_RELEASE_CHECK_RATE */ 6996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USE_BUILTIN_FFS 7006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_BUILTIN_FFS 0 7016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_BUILTIN_FFS */ 7026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USE_DEV_RANDOM 7036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_DEV_RANDOM 0 7046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_DEV_RANDOM */ 7056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef NO_MALLINFO 7066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NO_MALLINFO 0 7076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 7086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MALLINFO_FIELD_TYPE 7096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MALLINFO_FIELD_TYPE size_t 7106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLINFO_FIELD_TYPE */ 7116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef NO_MALLOC_STATS 7126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NO_MALLOC_STATS 0 7136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLOC_STATS */ 7146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef NO_SEGMENT_TRAVERSAL 7156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NO_SEGMENT_TRAVERSAL 0 7166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_SEGMENT_TRAVERSAL */ 7176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 7196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mallopt tuning options. SVID/XPG defines four standard parameter 7206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao numbers for mallopt, normally defined in malloc.h. None of these 7216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are used in this malloc, so setting them has no effect. But this 7226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc does support the following options. 7236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 7246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define M_TRIM_THRESHOLD (-1) 7266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define M_GRANULARITY (-2) 7276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define M_MMAP_THRESHOLD (-3) 7286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------------ Mallinfo declarations ------------------------ */ 7306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 7326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 7336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This version of malloc supports the standard SVID/XPG mallinfo 7346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao routine that returns a struct containing usage properties and 7356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao statistics. It should work on any system that has a 7366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /usr/include/malloc.h defining struct mallinfo. The main 7376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao declaration needed is the mallinfo struct that is returned (by-copy) 7386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao by mallinfo(). The malloinfo struct contains a bunch of fields that 7396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are not even meaningful in this version of malloc. These fields are 7406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are instead filled by mallinfo() with other numbers that might be of 7416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao interest. 7426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao HAVE_USR_INCLUDE_MALLOC_H should be set if you have a 7446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /usr/include/malloc.h file that includes a declaration of struct 7456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mallinfo. If so, it is included; else a compliant version is 7466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao declared below. These must be precisely the same for mallinfo() to 7476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao work. The original SVID version of this struct, defined on most 7486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao systems with mallinfo, declares all fields as ints. But some others 7496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao define as unsigned long. If your system defines the fields using a 7506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao type of different width than listed here, you MUST #include your 7516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system version and #define HAVE_USR_INCLUDE_MALLOC_H. 7526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 7536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define HAVE_USR_INCLUDE_MALLOC_H */ 7556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef HAVE_USR_INCLUDE_MALLOC_H 7576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include "/usr/include/malloc.h" 7586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* HAVE_USR_INCLUDE_MALLOC_H */ 7596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef STRUCT_MALLINFO_DECLARED 7606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */ 7616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define _STRUCT_MALLINFO 7626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define STRUCT_MALLINFO_DECLARED 1 7636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct mallinfo { 7646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ 7656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ 7666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE smblks; /* always 0 */ 7676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE hblks; /* always 0 */ 7686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ 7696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ 7706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ 7716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ 7726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE fordblks; /* total free space */ 7736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ 7746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 7756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* STRUCT_MALLINFO_DECLARED */ 7766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_USR_INCLUDE_MALLOC_H */ 7776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 7786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 7806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Try to persuade compilers to inline. The most critical functions for 7816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao inlining are defined as macros, so these aren't used for them. 7826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 7836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 7846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef FORCEINLINE 7856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #if defined(__GNUC__) 7866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FORCEINLINE __inline __attribute__ ((always_inline)) 7876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #elif defined(_MSC_VER) 7886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define FORCEINLINE __forceinline 7896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif 7906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 7916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef NOINLINE 7926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #if defined(__GNUC__) 7936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define NOINLINE __attribute__ ((noinline)) 7946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #elif defined(_MSC_VER) 7956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define NOINLINE __declspec(noinline) 7966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else 7976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define NOINLINE 7986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif 7996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 8006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 8026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoextern "C" { 8036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef FORCEINLINE 8046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define FORCEINLINE inline 8056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 8066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 8076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef FORCEINLINE 8086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define FORCEINLINE 8096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 8106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 8126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------- Declarations of public routines ------------------- */ 8146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USE_DL_PREFIX 8166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlcalloc calloc 8176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlfree free 8186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc malloc 8196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmemalign memalign 8206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlposix_memalign posix_memalign 8216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlrealloc realloc 8226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlrealloc_in_place realloc_in_place 8236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlvalloc valloc 8246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlpvalloc pvalloc 8256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmallinfo mallinfo 8266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmallopt mallopt 8276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_trim malloc_trim 8286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_stats malloc_stats 8296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_usable_size malloc_usable_size 8306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_footprint malloc_footprint 8316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_max_footprint malloc_max_footprint 8326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_footprint_limit malloc_footprint_limit 8336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_set_footprint_limit malloc_set_footprint_limit 8346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlmalloc_inspect_all malloc_inspect_all 8356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlindependent_calloc independent_calloc 8366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlindependent_comalloc independent_comalloc 8376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define dlbulk_free bulk_free 8386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_DL_PREFIX */ 8396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 8416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc(size_t n) 8426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns a pointer to a newly allocated chunk of at least n bytes, or 8436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao null if no space is available, in which case errno is set to ENOMEM 8446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao on ANSI C systems. 8456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If n is zero, malloc returns a minimum-sized chunk. (The minimum 8476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size is 16 bytes on most 32bit systems, and 32 bytes on 64bit 8486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao systems.) Note that size_t is an unsigned type, so calls with 8496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao arguments that would be negative if signed are interpreted as 8506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao requests for huge amounts of space, which will often fail. The 8516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao maximum supported value of n differs across systems, but is in all 8526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cases less than the maximum representable value of a size_t. 8536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 8546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlmalloc(size_t); 8556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 8576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free(void* p) 8586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Releases the chunk of memory pointed to by p, that had been previously 8596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocated using malloc or a related routine such as realloc. 8606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao It has no effect if p is null. If p was not malloced or already 8616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao freed, free(p) will by default cause the current program to abort. 8626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 8636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void dlfree(void*); 8646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 8666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao calloc(size_t n_elements, size_t element_size); 8676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns a pointer to n_elements * element_size bytes, with all locations 8686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set to zero. 8696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 8706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlcalloc(size_t, size_t); 8716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 8736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc(void* p, size_t n) 8746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns a pointer to a chunk of size n that contains the same data 8756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao as does chunk p up to the minimum of (n, p's size) bytes, or null 8766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if no space is available. 8776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The returned pointer may or may not be the same as p. The algorithm 8796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao prefers extending p in most cases when possible, otherwise it 8806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao employs the equivalent of a malloc-copy-free sequence. 8816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If p is null, realloc is equivalent to malloc. 8836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If space is not available, realloc returns null, errno is set (if on 8856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ANSI) and p is NOT freed. 8866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if n is for fewer bytes than already held by p, the newly unused 8886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space is lopped off and freed if possible. realloc with a size 8896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao argument of zero (re)allocates a minimum-sized chunk. 8906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The old unix realloc convention of allowing the last-free'd chunk 8926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to be used as an argument to realloc is not supported. 8936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 8946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlrealloc(void*, size_t); 8956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 8976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc_in_place(void* p, size_t n) 8986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Resizes the space allocated for p to size n, only if this can be 8996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao done without moving p (i.e., only if there is adjacent space 9006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao available if n is greater than p's current allocated size, or n is 9016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao less than or equal to p's size). This may be used instead of plain 9026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc if an alternative allocation strategy is needed upon failure 9036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to expand space; for example, reallocation of a buffer that must be 9046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory-aligned or cleared. You can use realloc_in_place to trigger 9056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao these alternatives only when needed. 9066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns p if successful; otherwise null. 9086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t); 9106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memalign(size_t alignment, size_t n); 9136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns a pointer to a newly allocated chunk of n bytes, aligned 9146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in accord with the alignment argument. 9156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The alignment argument should be a power of two. If the argument is 9176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao not a power of two, the nearest greater power is used. 9186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 8-byte alignment is guaranteed by normal malloc calls, so don't 9196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bother calling memalign with an argument of 8 or less. 9206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Overreliance on memalign is a sure way to fragment space. 9226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlmemalign(size_t, size_t); 9246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int posix_memalign(void** pp, size_t alignment, size_t n); 9276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Allocates a chunk of n bytes, aligned in accord with the alignment 9286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao argument. Differs from memalign only in that it (1) assigns the 9296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocated memory to *pp rather than returning it, (2) fails and 9306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao returns EINVAL if the alignment is not a power of two (3) fails and 9316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao returns ENOMEM if memory cannot be allocated. 9326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t); 9346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao valloc(size_t n); 9376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Equivalent to memalign(pagesize, n), where pagesize is the page 9386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size of the system. If the pagesize is unknown, 4096 is used. 9396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlvalloc(size_t); 9416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mallopt(int parameter_number, int parameter_value) 9446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Sets tunable parameters The format is to provide a 9456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (parameter-number, parameter-value) pair. mallopt then sets the 9466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao corresponding parameter to the argument value if it can (i.e., so 9476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao long as the value is meaningful), and returns 1 if successful else 9486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 0. To workaround the fact that mallopt is specified to use int, 9496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao not size_t parameters, the value -1 is specially treated as the 9506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao maximum unsigned size_t value. 9516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SVID/XPG/ANSI defines four standard param numbers for mallopt, 9536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao normally defined in malloc.h. None of these are use in this malloc, 9546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao so setting them has no effect. But this malloc also supports other 9556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao options in mallopt. See below for details. Briefly, supported 9566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao parameters are as follows (listed defaults are for "typical" 9576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao configurations). 9586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Symbol param # default allowed param values 9606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) 9616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao M_GRANULARITY -2 page size any power of 2 >= page size 9626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) 9636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int dlmallopt(int, int); 9656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_footprint(); 9686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns the number of bytes obtained from the system. The total 9696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao number of bytes allocated by malloc, realloc etc., is less than this 9706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao value. Unlike mallinfo, this function returns only a precomputed 9716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result, so can be called frequently to monitor memory consumption. 9726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Even if locks are otherwise defined, this function does not use them, 9736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao so results might not be up to date. 9746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t dlmalloc_footprint(void); 9766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_max_footprint(); 9796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns the maximum number of bytes obtained from the system. This 9806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao value will be greater than current footprint if deallocated space 9816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao has been reclaimed by the system. The peak number of bytes allocated 9826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao by malloc, realloc etc., is less than this value. Unlike mallinfo, 9836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this function returns only a precomputed result, so can be called 9846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao frequently to monitor memory consumption. Even if locks are 9856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao otherwise defined, this function does not use them, so results might 9866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao not be up to date. 9876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t dlmalloc_max_footprint(void); 9896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 9906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 9916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_footprint_limit(); 9926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns the number of bytes that the heap is allowed to obtain from 9936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the system, returning the last value returned by 9946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_set_footprint_limit, or the maximum size_t value if 9956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao never set. The returned value reflects a permission. There is no 9966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao guarantee that this number of bytes can actually be obtained from 9976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the system. 9986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 9996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t dlmalloc_footprint_limit(); 10006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 10026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_set_footprint_limit(); 10036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Sets the maximum number of bytes to obtain from the system, causing 10046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao failure returns from malloc and related functions upon attempts to 10056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao exceed this value. The argument value may be subject to page 10066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rounding to an enforceable limit; this actual value is returned. 10076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Using an argument of the maximum possible size_t effectively 10086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disables checks. If the argument is less than or equal to the 10096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao current malloc_footprint, then all future allocations that require 10106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao additional system memory will fail. However, invocation cannot 10116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao retroactively deallocate existing used memory. 10126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 10136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes); 10146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MALLOC_INSPECT_ALL 10166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 10176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_inspect_all(void(*handler)(void *start, 10186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *end, 10196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used_bytes, 10206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* callback_arg), 10216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* arg); 10226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Traverses the heap and calls the given handler for each managed 10236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao region, skipping all bytes that are (or may be) used for bookkeeping 10246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao purposes. Traversal does not include include chunks that have been 10256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao directly memory mapped. Each reported region begins at the start 10266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao address, and continues up to but not including the end address. The 10276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao first used_bytes of the region contain allocated data. If 10286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used_bytes is zero, the region is unallocated. The handler is 10296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao invoked with the given callback argument. If locks are defined, they 10306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are held during the entire traversal. It is a bad idea to invoke 10316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao other malloc functions from within the handler. 10326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao For example, to count the number of in-use chunks with size greater 10346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao than 1000, you could write: 10356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static int count = 0; 10366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void count_chunks(void* start, void* end, size_t used, void* arg) { 10376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (used >= 1000) ++count; 10386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 10396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao then: 10406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_inspect_all(count_chunks, NULL); 10416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. 10436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 10446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*), 10456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* arg); 10466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_INSPECT_ALL */ 10486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 10506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 10516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mallinfo() 10526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns (by copy) a struct containing various summary statistics: 10536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao arena: current total non-mmapped bytes allocated from system 10556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ordblks: the number of free chunks 10566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao smblks: always zero. 10576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao hblks: current number of mmapped regions 10586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao hblkhd: total bytes held in mmapped regions 10596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao usmblks: the maximum total allocated space. This will be greater 10606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao than current total if trimming has occurred. 10616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fsmblks: always zero 10626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao uordblks: current total allocated space (normal or mmapped) 10636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fordblks: total free space 10646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao keepcost: the maximum number of bytes that could ideally be released 10656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao back to system via malloc_trim. ("ideally" means that 10666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao it ignores page restrictions etc.) 10676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Because these fields are ints, but internal bookkeeping may 10696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be kept as longs, the reported values may wrap around zero and 10706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao thus be inaccurate. 10716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 10726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT struct mallinfo dlmallinfo(void); 10736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 10746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 10766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); 10776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_calloc is similar to calloc, but instead of returning a 10796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao single cleared space, it returns an array of pointers to n_elements 10806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent elements that can hold contents of size elem_size, each 10816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of which starts out cleared, and can be independently freed, 10826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloc'ed etc. The elements are guaranteed to be adjacently 10836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocated (this is not guaranteed to occur with multiple callocs or 10846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mallocs), which may also improve cache locality in some 10856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao applications. 10866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The "chunks" argument is optional (i.e., may be null, which is 10886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao probably the most typical usage). If it is null, the returned array 10896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is itself dynamically allocated and should also be freed when it is 10906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao no longer needed. Otherwise, the chunks array must be of at least 10916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao n_elements in length. It is filled in with the pointers to the 10926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks. 10936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao In either case, independent_calloc returns this pointer array, or 10956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao null if the allocation failed. If n_elements is zero and "chunks" 10966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is null, it returns a chunk representing an array with zero elements 10976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (which should be freed if not wanted). 10986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 10996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each element must be freed when it is no longer needed. This can be 11006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao done all at once using bulk_free. 11016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_calloc simplifies and speeds up implementations of many 11036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao kinds of pools. It may also be useful when constructing large data 11046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao structures that initially have a fixed number of fixed-sized nodes, 11056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao but the number is not known at compile time, and some of the nodes 11066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao may later need to be freed. For example: 11076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Node { int item; struct Node* next; }; 11096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Node* build_list() { 11116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Node** pool; 11126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int n = read_number_of_nodes_needed(); 11136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (n <= 0) return 0; 11146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); 11156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pool == 0) die(); 11166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // organize into a linked list... 11176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Node* first = pool[0]; 11186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i < n-1; ++i) 11196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pool[i]->next = pool[i+1]; 11206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free(pool); // Can now free the array (or not, if it is needed later) 11216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return first; 11226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 11236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 11246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**); 11256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 11276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); 11286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_comalloc allocates, all at once, a set of n_elements 11306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks with sizes indicated in the "sizes" array. It returns 11316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao an array of pointers to these elements, each of which can be 11326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independently freed, realloc'ed etc. The elements are guaranteed to 11336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be adjacently allocated (this is not guaranteed to occur with 11346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao multiple callocs or mallocs), which may also improve cache locality 11356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in some applications. 11366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The "chunks" argument is optional (i.e., may be null). If it is null 11386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the returned array is itself dynamically allocated and should also 11396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be freed when it is no longer needed. Otherwise, the chunks array 11406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao must be of at least n_elements in length. It is filled in with the 11416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointers to the chunks. 11426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao In either case, independent_comalloc returns this pointer array, or 11446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao null if the allocation failed. If n_elements is zero and chunks is 11456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao null, it returns a chunk representing an array with zero elements 11466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (which should be freed if not wanted). 11476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each element must be freed when it is no longer needed. This can be 11496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao done all at once using bulk_free. 11506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_comallac differs from independent_calloc in that each 11526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao element may have a different size, and also that it does not 11536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao automatically clear elements. 11546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao independent_comalloc can be used to speed up allocation in cases 11566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao where several structs or objects must always be allocated at the 11576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao same time. For example: 11586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Head { ... } 11606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Foot { ... } 11616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void send_message(char* msg) { 11636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int msglen = strlen(msg); 11646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; 11656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* chunks[3]; 11666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (independent_comalloc(3, sizes, chunks) == 0) 11676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao die(); 11686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Head* head = (struct Head*)(chunks[0]); 11696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* body = (char*)(chunks[1]); 11706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct Foot* foot = (struct Foot*)(chunks[2]); 11716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // ... 11726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 11736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao In general though, independent_comalloc is worth using only for 11756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao larger values of n_elements. For small values, you probably won't 11766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao detect enough difference from series of malloc calls to bother. 11776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Overuse of independent_comalloc can increase overall memory usage, 11796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao since it cannot reuse existing noncontiguous small chunks that 11806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao might be available for some of the elements. 11816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 11826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**); 11836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 11856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bulk_free(void* array[], size_t n_elements) 11866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Frees and clears (sets to null) each non-null pointer in the given 11876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao array. This is likely to be faster than freeing them one-by-one. 11886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If footers are used, pointers that have been allocated in different 11896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspaces are not freed or cleared, and the count of all such pointers 11906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is returned. For large arrays of pointers with poor locality, it 11916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao may be worthwhile to sort this array before calling bulk_free. 11926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 11936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t dlbulk_free(void**, size_t n_elements); 11946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 11956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 11966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pvalloc(size_t n); 11976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Equivalent to valloc(minimum-page-that-holds(n)), that is, 11986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao round up n to nearest pagesize. 11996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 12006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* dlpvalloc(size_t); 12016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_trim(size_t pad); 12046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If possible, gives memory back to the system (via negative arguments 12066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to sbrk) if there is unused memory at the `high' end of the malloc 12076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pool or in unused MMAP segments. You can call this after freeing 12086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao large blocks of memory to potentially reduce the system-level memory 12096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao requirements of a program. However, it cannot guarantee to reduce 12106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory. Under some allocation patterns, some large free blocks of 12116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory will be locked between two used chunks, so they cannot be 12126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao given back to the system. 12136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The `pad' argument to malloc_trim represents the amount of free 12156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao trailing space to leave untrimmed. If this argument is zero, only 12166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the minimum amount of memory to maintain internal data structures 12176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao will be left. Non-zero arguments can be supplied to maintain enough 12186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao trailing space to service future expected allocations without having 12196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to re-obtain memory from the system. 12206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Malloc_trim returns 1 if it actually released any memory, else 0. 12226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int dlmalloc_trim(size_t); 12246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_stats(); 12276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Prints on stderr the amount of space obtained from the system (both 12286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao via sbrk and mmap), the maximum amount (which may be more than 12296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao current if malloc_trim and/or munmap got called), and the current 12306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao number of bytes allocated via malloc (or realloc, etc) but not yet 12316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao freed. Note that this is the number of bytes allocated, not the 12326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao number requested. It will be larger than the number requested 12336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao because of alignment and bookkeeping overhead. Because it includes 12346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignment wastage as being in use, this figure may be greater than 12356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao zero even when no user-level chunks are allocated. 12366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The reported current and maximum system memory can be inaccurate if 12386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao a program makes other calls to system memory allocation functions 12396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (normally sbrk) outside of malloc. 12406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_stats prints only the most commonly interesting statistics. 12426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao More information can be obtained by calling mallinfo. 12436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void dlmalloc_stats(void); 12456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_usable_size(void* p); 12486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Returns the number of bytes you can actually use in 12506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao an allocated chunk, which may be more than you requested (although 12516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao often not) due to alignment and minimum size constraints. 12526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao You can use this many bytes without worrying about 12536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao overwriting other allocated objects. This is not a particularly great 12546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao programming practice. malloc_usable_size can be more useful in 12556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao debugging and assertions, for example: 12566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = malloc(n); 12586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(malloc_usable_size(p) >= 256); 12596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* BEGIN android-changed: added const */ 12616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_usable_size(const void*); 12626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* END android-change */ 12636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ONLY_MSPACES */ 12656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MSPACES 12676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace is an opaque type representing an independent 12706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao region of space that supports mspace_malloc, etc. 12716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef void* mspace; 12736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao create_mspace creates and returns a new independent space with the 12766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao given initial capacity, or, if 0, the default granularity size. It 12776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao returns null if there is no system memory available to create the 12786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space. If argument locked is non-zero, the space uses a separate 12796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lock to control access. The capacity of the space will grow 12806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dynamically as needed to service mspace_malloc requests. You can 12816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao control the sizes of incremental increases of this space by 12826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compiling with a different DEFAULT_GRANULARITY or dynamically 12836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao setting with mallopt(M_GRANULARITY, value). 12846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked); 12866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao destroy_mspace destroys the given space, and attempts to return all 12896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of its memory back to the system, returning the total number of 12906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bytes freed. After destruction, the results of access to all memory 12916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used by the space become undefined. 12926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 12936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t destroy_mspace(mspace msp); 12946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 12956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 12966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao create_mspace_with_base uses the memory supplied as the initial base 12976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this 12986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space is used for bookkeeping, so the capacity must be at least this 12996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao large. (Otherwise 0 is returned.) When this initial space is 13006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao exhausted, additional memory will be obtained from the system. 13016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Destroying this space will deallocate all additionally allocated 13026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space (if possible) but not the initial base. 13036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked); 13056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_track_large_chunks controls whether requests for large chunks 13086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are allocated in their own untracked mmapped regions, separate from 13096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao others in this mspace. By default large chunks are not tracked, 13106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao which reduces fragmentation. However, such chunks are not 13116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao necessarily released to the system upon destroy_mspace. Enabling 13126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tracking by setting to true may increase fragmentation, but avoids 13136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao leakage when relying on destroy_mspace to release all memory 13146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocated using this space. The function returns the previous 13156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao setting. 13166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable); 13186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_malloc behaves as malloc, but operates within 13226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes); 13256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_free behaves as free, but operates within 13286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If compiled with FOOTERS==1, mspace_free is not actually needed. 13316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free may be called instead of mspace_free because freed chunks from 13326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao any space are handled by their originating spaces. 13336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void mspace_free(mspace msp, void* mem); 13356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_realloc behaves as realloc, but operates within 13386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If compiled with FOOTERS==1, mspace_realloc is not actually 13416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao needed. realloc may be called instead of mspace_realloc because 13426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao realloced chunks from any space are handled by their originating 13436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao spaces. 13446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize); 13466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_calloc behaves as calloc, but operates within 13496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); 13526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_memalign behaves as memalign, but operates within 13556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); 13586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_independent_calloc behaves as independent_calloc, but 13616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao operates within the given space. 13626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements, 13646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t elem_size, void* chunks[]); 13656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_independent_comalloc behaves as independent_comalloc, but 13686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao operates within the given space. 13696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements, 13716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sizes[], void* chunks[]); 13726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_footprint() returns the number of bytes obtained from the 13756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system for this space. 13766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t mspace_footprint(mspace msp); 13786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_max_footprint() returns the peak number of bytes obtained from the 13816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system for this space. 13826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp); 13846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 13876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_mallinfo behaves as mallinfo, but reports properties of 13896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the given space. 13906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp); 13926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 13936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 13956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_usable_size(void* p) behaves the same as malloc_usable_size; 13966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 13976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT size_t mspace_usable_size(const void* mem); 13986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 13996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 14006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_malloc_stats behaves as malloc_stats, but reports 14016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao properties of the given space. 14026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 14036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT void mspace_malloc_stats(mspace msp); 14046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 14066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_trim behaves as malloc_trim, but 14076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao operates within the given space. 14086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 14096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad); 14106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 14126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao An alias for mallopt. 14136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 14146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoDLMALLOC_EXPORT int mspace_mallopt(int, int); 14156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MSPACES */ 14176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 14196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} /* end of extern "C" */ 14206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 14216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 14236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ======================================================================== 14246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao To make a fully customizable malloc.h header file, cut everything 14256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao above this line, put into file malloc.h, edit to suit, and #include it 14266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao on the next line, as well as in programs that use this malloc. 14276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ======================================================================== 14286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 14296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #include "malloc.h" */ 14316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/*------------------------------ internal #includes ---------------------- */ 14336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef _MSC_VER 14356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ 14366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* _MSC_VER */ 14376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLOC_STATS 14386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <stdio.h> /* for printing in malloc_stats */ 14396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLOC_STATS */ 14406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_ERRNO_H 14416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <errno.h> /* for MALLOC_FAILURE_ACTION */ 14426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_ERRNO_H */ 14436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef DEBUG 14446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ABORT_ON_ASSERT_FAILURE 14456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#undef assert 14466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define assert(x) if(!(x)) ABORT 14476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* ABORT_ON_ASSERT_FAILURE */ 14486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <assert.h> 14496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ABORT_ON_ASSERT_FAILURE */ 14506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* DEBUG */ 14516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef assert 14526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define assert(x) 14536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 14546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DEBUG 0 14556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEBUG */ 14566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !defined(WIN32) && !defined(LACKS_TIME_H) 14576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <time.h> /* for magic initialization */ 14586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 14596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_STDLIB_H 14606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <stdlib.h> /* for abort() */ 14616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_STDLIB_H */ 14626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_STRING_H 14636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <string.h> /* for memset etc */ 14646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_STRING_H */ 14656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_BUILTIN_FFS 14666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_STRINGS_H 14676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <strings.h> /* for ffs */ 14686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_STRINGS_H */ 14696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_BUILTIN_FFS */ 14706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 14716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_SYS_MMAN_H 14726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ 14736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if (defined(linux) && !defined(__USE_GNU)) 14746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define __USE_GNU 1 14756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <sys/mman.h> /* for mmap */ 14766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#undef __USE_GNU 14776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 14786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <sys/mman.h> /* for mmap */ 14796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* linux */ 14806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_SYS_MMAN_H */ 14816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_FCNTL_H 14826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <fcntl.h> 14836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_FCNTL_H */ 14846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 14856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LACKS_UNISTD_H 14866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <unistd.h> /* for sbrk, sysconf */ 14876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* LACKS_UNISTD_H */ 14886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) 14896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoextern void* sbrk(ptrdiff_t); 14906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FreeBSD etc */ 14916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LACKS_UNISTD_H */ 14926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 14936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Declarations for locking */ 14946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS 14956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 14966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined (__SVR4) && defined (__sun) /* solaris */ 14976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <thread.h> 14986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif !defined(LACKS_SCHED_H) 14996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <sched.h> 15006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* solaris or LACKS_SCHED_H */ 15016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS 15026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#include <pthread.h> 15036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_RECURSIVE_LOCKS ... */ 15046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(_MSC_VER) 15056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef _M_AMD64 15066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* These are already defined on AMD64 builds */ 15076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 15086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoextern "C" { 15096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 15106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); 15116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoLONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); 15126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 15136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 15146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 15156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* _M_AMD64 */ 15166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#pragma intrinsic (_InterlockedCompareExchange) 15176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#pragma intrinsic (_InterlockedExchange) 15186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define interlockedcompareexchange _InterlockedCompareExchange 15196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define interlockedexchange _InterlockedExchange 15206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(WIN32) && defined(__GNUC__) 15216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) 15226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define interlockedexchange __sync_lock_test_and_set 15236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* Win32 */ 15246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* USE_LOCKS */ 15256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 15266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef LOCK_AT_FORK 15286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define LOCK_AT_FORK 0 15296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 15306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Declarations for bit scanning on win32 */ 15326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(_MSC_VER) && _MSC_VER>=1300 15336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ 15346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 15356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoextern "C" { 15366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 15376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaounsigned char _BitScanForward(unsigned long *index, unsigned long mask); 15386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaounsigned char _BitScanReverse(unsigned long *index, unsigned long mask); 15396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef __cplusplus 15406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 15416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* __cplusplus */ 15426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define BitScanForward _BitScanForward 15446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define BitScanReverse _BitScanReverse 15456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#pragma intrinsic(_BitScanForward) 15466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#pragma intrinsic(_BitScanReverse) 15476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* BitScanForward */ 15486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ 15496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 15516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef malloc_getpagesize 15526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ 15536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifndef _SC_PAGE_SIZE 15546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define _SC_PAGE_SIZE _SC_PAGESIZE 15556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef _SC_PAGE_SIZE 15586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) 15596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) 15616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extern size_t getpagesize(); 15626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize getpagesize() 15636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef WIN32 /* use supplied emulation of getpagesize */ 15656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize getpagesize() 15666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifndef LACKS_SYS_PARAM_H 15686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# include <sys/param.h> 15696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef EXEC_PAGESIZE 15716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize EXEC_PAGESIZE 15726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef NBPG 15746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifndef CLSIZE 15756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize NBPG 15766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize (NBPG * CLSIZE) 15786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef NBPC 15816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize NBPC 15826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else 15836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# ifdef PAGESIZE 15846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize PAGESIZE 15856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# else /* just guess */ 15866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# define malloc_getpagesize ((size_t)4096U) 15876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao# endif 15946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 15956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 15966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------- size_t and alignment properties -------------------- */ 15986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 15996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The byte and bit size of a size_t */ 16006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_SIZE (sizeof(size_t)) 16016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_BITSIZE (sizeof(size_t) << 3) 16026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Some constants coerced to size_t */ 16046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Annoying but necessary to avoid errors on some platforms */ 16056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_ZERO ((size_t)0) 16066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_ONE ((size_t)1) 16076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_TWO ((size_t)2) 16086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIZE_T_FOUR ((size_t)4) 16096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) 16106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) 16116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) 16126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) 16136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The bit mask value corresponding to MALLOC_ALIGNMENT */ 16156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) 16166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* True if address a has acceptable alignment */ 16186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) 16196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* the number of bytes to offset an address to align it */ 16216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define align_offset(A)\ 16226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ 16236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) 16246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------------- MMAP preliminaries ------------------------- */ 16266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 16286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and 16296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao checks to fail so compiler optimizer can delete code rather than 16306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao using so many "#if"s. 16316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 16326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* MORECORE and MMAP must return MFAIL on failure */ 16356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MFAIL ((void*)(MAX_SIZE_T)) 16366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ 16376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 16396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 16416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) 16426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_PROT (PROT_READ|PROT_WRITE) 16436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) 16446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAP_ANONYMOUS MAP_ANON 16456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MAP_ANON */ 16466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef MAP_ANONYMOUS 16476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) 16486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) 16496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MAP_ANONYMOUS */ 16506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 16516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Nearly all versions of mmap support MAP_ANONYMOUS, so the following 16526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is unlikely to be needed, but is supplied just in case. 16536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 16546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_FLAGS (MAP_PRIVATE) 16556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ 16566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ 16576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (dev_zero_fd = open("/dev/zero", O_RDWR), \ 16586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ 16596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) 16606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MAP_ANONYMOUS */ 16616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) 16636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* WIN32 */ 16656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Win32 MMAP via VirtualAlloc */ 16676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE void* win32mmap(size_t size) { 16686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 16696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (ptr != 0)? ptr: MFAIL; 16706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 16716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ 16736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE void* win32direct_mmap(size_t size) { 16746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, 16756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao PAGE_READWRITE); 16766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (ptr != 0)? ptr: MFAIL; 16776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 16786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* This function supports releasing coalesed segments */ 16806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE int win32munmap(void* ptr, size_t size) { 16816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MEMORY_BASIC_INFORMATION minfo; 16826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* cptr = (char*)ptr; 16836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (size) { 16846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) 16856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return -1; 16866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || 16876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao minfo.State != MEM_COMMIT || minfo.RegionSize > size) 16886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return -1; 16896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) 16906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return -1; 16916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cptr += minfo.RegionSize; 16926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size -= minfo.RegionSize; 16936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 16946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 16956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 16966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 16976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_DEFAULT(s) win32mmap(s) 16986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) 16996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) 17006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 17016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 17026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MREMAP 17046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 17056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) 17066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 17076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MREMAP */ 17086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/** 17106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Define CALL_MORECORE 17116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 17126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MORECORE 17136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #ifdef MORECORE 17146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MORECORE(S) MORECORE(S) 17156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else /* MORECORE */ 17166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MORECORE(S) MORECORE_DEFAULT(S) 17176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif /* MORECORE */ 17186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* HAVE_MORECORE */ 17196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MORECORE(S) MFAIL 17206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MORECORE */ 17216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/** 17236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP 17246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 17256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 17266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define USE_MMAP_BIT (SIZE_T_ONE) 17276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #ifdef MMAP 17296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MMAP(s) MMAP(s) 17306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else /* MMAP */ 17316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MMAP(s) MMAP_DEFAULT(s) 17326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif /* MMAP */ 17336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #ifdef MUNMAP 17346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) 17356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else /* MUNMAP */ 17366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) 17376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif /* MUNMAP */ 17386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #ifdef DIRECT_MMAP 17396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) 17406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else /* DIRECT_MMAP */ 17416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) 17426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif /* DIRECT_MMAP */ 17436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* HAVE_MMAP */ 17446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define USE_MMAP_BIT (SIZE_T_ZERO) 17456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define MMAP(s) MFAIL 17476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define MUNMAP(a, s) (-1) 17486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define DIRECT_MMAP(s) MFAIL 17496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) 17506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MMAP(s) MMAP(s) 17516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) 17526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP */ 17536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/** 17556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Define CALL_MREMAP 17566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 17576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP && HAVE_MREMAP 17586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #ifdef MREMAP 17596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) 17606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #else /* MREMAP */ 17616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) 17626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #endif /* MREMAP */ 17636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* HAVE_MMAP && HAVE_MREMAP */ 17646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL 17656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* HAVE_MMAP && HAVE_MREMAP */ 17666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* mstate bit set if continguous morecore disabled or failed */ 17686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_NONCONTIGUOUS_BIT (4U) 17696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* segment bit set in create_mspace_with_base */ 17716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define EXTERN_BIT (8U) 17726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* --------------------------- Lock preliminaries ------------------------ */ 17756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 17776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao When locks are defined, there is one global lock, plus 17786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao one per-mspace lock. 17796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The global lock_ensures that mparams.magic and other unique 17816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams values are initialized only once. It also protects 17826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sequences of calls to MORECORE. In many cases sys_alloc requires 17836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao two calls, that should not be interleaved with calls by other 17846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao threads. This does not protect against direct calls to MORECORE 17856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao by other threads not using this lock, so there is still code to 17866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cope the best we can on interference. 17876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Per-mspace locks surround calls to malloc, free, etc. 17896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao By default, locks are simple non-reentrant mutexes. 17906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Because lock-protected regions generally have bounded times, it is 17926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao OK to use the supplied simple spinlocks. Spinlocks are likely to 17936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao improve performance for lightly contended applications, but worsen 17946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao performance under heavy contention. 17956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 17966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If USE_LOCKS is > 1, the definitions of lock routines here are 17976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bypassed, in which case you will need to define the type MLOCK_T, 17986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK 17996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and TRY_LOCK. You must also declare a 18006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static MLOCK_T malloc_global_mutex = { initialization values };. 18016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 18036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !USE_LOCKS 18056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_LOCK_BIT (0U) 18066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INITIAL_LOCK(l) (0) 18076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DESTROY_LOCK(l) (0) 18086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_MALLOC_GLOBAL_LOCK() 18096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_MALLOC_GLOBAL_LOCK() 18106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 18126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS > 1 18136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- User-defined locks ------------------------ */ 18146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Define your own lock implementation here */ 18156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define INITIAL_LOCK(lk) ... */ 18166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define DESTROY_LOCK(lk) ... */ 18176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define ACQUIRE_LOCK(lk) ... */ 18186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define RELEASE_LOCK(lk) ... */ 18196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* #define TRY_LOCK(lk) ... */ 18206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* static MLOCK_T malloc_global_mutex = ... */ 18216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif USE_SPIN_LOCKS 18236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* First, define CAS_LOCK and CLEAR_LOCK on ints */ 18256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Note CAS_LOCK defined to return 0 on success */ 18266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) 18286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1) 18296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CLEAR_LOCK(sl) __sync_lock_release(sl) 18306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) 18326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Custom spin locks for older gcc on x86 */ 18336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE int x86_cas_lock(int *sl) { 18346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int ret; 18356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int val = 1; 18366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int cmp = 0; 18376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao __asm__ __volatile__ ("lock; cmpxchgl %1, %2" 18386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "=a" (ret) 18396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "r" (val), "m" (*(sl)), "0"(cmp) 18406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "memory", "cc"); 18416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ret; 18426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 18436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE void x86_clear_lock(int* sl) { 18456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(*sl != 0); 18466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int prev = 0; 18476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int ret; 18486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao __asm__ __volatile__ ("lock; xchgl %0, %1" 18496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "=r" (ret) 18506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "m" (*(sl)), "0"(prev) 18516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : "memory"); 18526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 18536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CAS_LOCK(sl) x86_cas_lock(sl) 18556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CLEAR_LOCK(sl) x86_clear_lock(sl) 18566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* Win32 MSC */ 18586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CAS_LOCK(sl) interlockedexchange(sl, (LONG)1) 18596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CLEAR_LOCK(sl) interlockedexchange (sl, (LONG)0) 18606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ... gcc spins locks ... */ 18626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* How to yield for a spin lock */ 18646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SPINS_PER_YIELD 63 18656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(_MSC_VER) 18666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */ 18676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE) 18686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined (__SVR4) && defined (__sun) /* solaris */ 18696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SPIN_LOCK_YIELD thr_yield(); 18706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif !defined(LACKS_SCHED_H) 18716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SPIN_LOCK_YIELD sched_yield(); 18726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 18736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SPIN_LOCK_YIELD 18746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ... yield ... */ 18756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 18776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Plain spin locks use single word (embedded in malloc_states) */ 18786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int spin_acquire_lock(int *sl) { 18796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int spins = 0; 18806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { 18816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((++spins & SPINS_PER_YIELD) == 0) { 18826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SPIN_LOCK_YIELD; 18836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 18846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 18856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 18866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 18876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MLOCK_T int 18896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TRY_LOCK(sl) !CAS_LOCK(sl) 18906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_LOCK(sl) CLEAR_LOCK(sl) 18916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0) 18926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INITIAL_LOCK(sl) (*sl = 0) 18936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DESTROY_LOCK(sl) (0) 18946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic MLOCK_T malloc_global_mutex = 0; 18956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 18966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* USE_RECURSIVE_LOCKS */ 18976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* types for lock owners */ 18986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef WIN32 18996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define THREAD_ID_T DWORD 19006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CURRENT_THREAD GetCurrentThreadId() 19016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define EQ_OWNER(X,Y) ((X) == (Y)) 19026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 19036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 19046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note: the following assume that pthread_t is a type that can be 19056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao initialized to (casted) zero. If this is not the case, you will need to 19066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao somehow redefine these or not use spin locks. 19076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 19086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define THREAD_ID_T pthread_t 19096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CURRENT_THREAD pthread_self() 19106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define EQ_OWNER(X,Y) pthread_equal(X, Y) 19116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 19126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_recursive_lock { 19146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int sl; 19156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int c; 19166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao THREAD_ID_T threadid; 19176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 19186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MLOCK_T struct malloc_recursive_lock 19206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0}; 19216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE void recursive_release_lock(MLOCK_T *lk) { 19236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(lk->sl != 0); 19246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (--lk->c == 0) { 19256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CLEAR_LOCK(&lk->sl); 19266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 19286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) { 19306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao THREAD_ID_T mythreadid = CURRENT_THREAD; 19316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int spins = 0; 19326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 19336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (*((volatile int *)(&lk->sl)) == 0) { 19346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!CAS_LOCK(&lk->sl)) { 19356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lk->threadid = mythreadid; 19366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lk->c = 1; 19376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 19386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (EQ_OWNER(lk->threadid, mythreadid)) { 19416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++lk->c; 19426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 19436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((++spins & SPINS_PER_YIELD) == 0) { 19456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SPIN_LOCK_YIELD; 19466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 19496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic FORCEINLINE int recursive_try_lock(MLOCK_T *lk) { 19516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao THREAD_ID_T mythreadid = CURRENT_THREAD; 19526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (*((volatile int *)(&lk->sl)) == 0) { 19536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!CAS_LOCK(&lk->sl)) { 19546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lk->threadid = mythreadid; 19556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lk->c = 1; 19566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 19576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (EQ_OWNER(lk->threadid, mythreadid)) { 19606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++lk->c; 19616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 19626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 19646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 19656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_LOCK(lk) recursive_release_lock(lk) 19676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TRY_LOCK(lk) recursive_try_lock(lk) 19686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk) 19696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0) 19706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DESTROY_LOCK(lk) (0) 19716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_RECURSIVE_LOCKS */ 19726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(WIN32) /* Win32 critical sections */ 19746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MLOCK_T CRITICAL_SECTION 19756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0) 19766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_LOCK(lk) LeaveCriticalSection(lk) 19776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TRY_LOCK(lk) TryEnterCriticalSection(lk) 19786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000)) 19796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0) 19806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NEED_GLOBAL_LOCK_INIT 19816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic MLOCK_T malloc_global_mutex; 19836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic volatile LONG malloc_global_mutex_status; 19846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 19856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Use spin loop to initialize global lock */ 19866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void init_malloc_global_mutex() { 19876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 19886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao long stat = malloc_global_mutex_status; 19896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (stat > 0) 19906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 19916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* transition to < 0 while initializing, then to > 0) */ 19926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (stat == 0 && 19936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) { 19946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao InitializeCriticalSection(&malloc_global_mutex); 19956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao interlockedexchange(&malloc_global_mutex_status, (LONG)1); 19966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 19976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 19986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SleepEx(0, FALSE); 19996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 20006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 20016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* pthreads-based locks */ 20036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MLOCK_T pthread_mutex_t 20046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk) 20056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_LOCK(lk) pthread_mutex_unlock(lk) 20066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TRY_LOCK(lk) (!pthread_mutex_trylock(lk)) 20076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INITIAL_LOCK(lk) pthread_init_lock(lk) 20086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define DESTROY_LOCK(lk) pthread_mutex_destroy(lk) 20096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE) 20116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Cope with old-style linux recursive lock initialization by adding */ 20126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* skipped internal declaration from pthread.h */ 20136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoextern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, 20146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int __kind)); 20156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP 20166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) 20176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_RECURSIVE_LOCKS ... */ 20186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; 20206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int pthread_init_lock (MLOCK_T *lk) { 20226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pthread_mutexattr_t attr; 20236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pthread_mutexattr_init(&attr)) return 1; 20246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 20256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; 20266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 20276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pthread_mutex_init(lk, &attr)) return 1; 20286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pthread_mutexattr_destroy(&attr)) return 1; 20296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 20306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 20316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ... lock types ... */ 20336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Common code for all lock types */ 20356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USE_LOCK_BIT (2U) 20366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK 20386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); 20396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 20406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef RELEASE_MALLOC_GLOBAL_LOCK 20426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); 20436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 20446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 20466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- Chunk representations ------------------------ */ 20486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 20506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (The following includes lightly edited explanations by Colin Plumb.) 20516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The malloc_chunk declaration below is misleading (but accurate and 20536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao necessary). It declares a "view" into memory allowing access to 20546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao necessary fields at known offsets from a given base. 20556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Chunks of memory are maintained using a `boundary tag' method as 20576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao originally described by Knuth. (See the paper by Paul Wilson 20586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such 20596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao techniques.) Sizes of free chunks are stored both in the front of 20606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao each chunk and at the end. This makes consolidating fragmented 20616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks into bigger chunks fast. The head fields also hold bits 20626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao representing whether chunks are free or in use. 20636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Here are some pictures to make it clearer. They are "exploded" to 20656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao show that the state of a chunk can be thought of as extending from 20666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the high 31 bits of the head field of its header through the 20676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao prev_foot and PINUSE_BIT bit of the following chunk header. 20686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao A chunk that's in use looks like: 20706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of previous chunk (if P = 0) | 20736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| 20756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of this chunk 1| +-+ 20766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | | 20786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +- -+ 20796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | | 20806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +- -+ 20816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | : 20826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +- size - sizeof(size_t) available payload bytes -+ 20836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : | 20846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +- -+ 20856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | | 20866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| 20886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of next chunk (may or may not be in use) | +-+ 20896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao And if it's free, it looks like this: 20926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 20936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +- -+ 20946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | User payload (must be in use, or we would have merged!) | 20956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| 20976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of this chunk 0| +-+ 20986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Next pointer | 21006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Prev pointer | 21026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | : 21046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +- size - sizeof(struct chunk) unused bytes -+ 21056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : | 21066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of this chunk | 21086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| 21106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of next chunk (must be in use, or we would have merged)| +-+ 21116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | : 21136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +- User payload -+ 21146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao : | 21156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao |0| 21176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+ 21186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note that since we always merge adjacent free chunks, the chunks 21196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao adjacent to a free chunk must be in use. 21206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Given a pointer to a chunk (which can be derived trivially from the 21226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao payload pointer) we can, in O(1) time, find out whether the adjacent 21236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks are free, and if so, unlink them from the lists that they 21246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao are on and merge them with the current chunk. 21256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Chunks always begin on even word boundaries, so the mem portion 21276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (which is returned to the user) is also on an even word boundary, and 21286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao thus at least double-word aligned. 21296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The P (PINUSE_BIT) bit, stored in the unused low-order bit of the 21316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk size (which is always a multiple of two words), is an in-use 21326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bit for the *previous* chunk. If that bit is *clear*, then the 21336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao word before the current chunk size contains the previous chunk 21346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size, and can be used to find the front of the previous chunk. 21356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The very first chunk allocated always has this bit set, preventing 21366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao access to non-existent (or non-owned) memory. If pinuse is set for 21376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao any given chunk, then you CANNOT determine the size of the 21386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao previous chunk, and might even get a memory addressing fault when 21396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao trying to do so. 21406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of 21426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the chunk size redundantly records whether the current chunk is 21436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao inuse (unless the chunk is mmapped). This redundancy enables usage 21446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao checks within free and realloc, and reduces indirection when freeing 21456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and consolidating chunks. 21466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each freshly allocated chunk must have both cinuse and pinuse set. 21486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao That is, each allocated chunk borders either a previously allocated 21496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and still in-use chunk, or the base of its memory arena. This is 21506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensured by making all allocations from the `lowest' part of any 21516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao found chunk. Further, no free chunk physically borders another one, 21526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao so each free chunk is known to be preceded and followed by either 21536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao inuse chunks or the ends of memory. 21546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note that the `foot' of the current chunk is actually represented 21566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao as the prev_foot of the NEXT chunk. This makes it easier to 21576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao deal with alignments etc but can be very confusing when trying 21586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to extend or adapt this code. 21596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The exceptions to all this are 21616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1. The special chunk `top' is the top-most available chunk (i.e., 21636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the one bordering the end of available memory). It is treated 21646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao specially. Top is never included in any bin, is used only if 21656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao no other chunk is available, and is released back to the 21666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao system if it is very large (see M_TRIM_THRESHOLD). In effect, 21676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the top chunk is treated as larger (and thus less well 21686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fitting) than any other available chunk. The top chunk 21696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao doesn't update its trailing size field since there is no next 21706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao contiguous chunk that would have to index off it. However, 21716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space is still allocated for it (TOP_FOOT_SIZE) to enable 21726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao separation or merging when space is extended. 21736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3. Chunks allocated via mmap, have both cinuse and pinuse bits 21756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cleared in their head fields. Because they are allocated 21766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao one-by-one, each must carry its own prev_foot field, which is 21776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao also used to hold the offset this chunk has within its mmapped 21786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao region, which is needed to preserve alignment. Each mmapped 21796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk is trailed by the first two fields of a fake next-chunk 21806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for sake of usage checks. 21816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 21836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_chunk { 21856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t prev_foot; /* Size of previous chunk (if free). */ 21866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t head; /* Size and inuse bits. */ 21876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_chunk* fd; /* double links -- used only if free. */ 21886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_chunk* bk; 21896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 21906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_chunk mchunk; 21926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_chunk* mchunkptr; 21936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ 21946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef unsigned int bindex_t; /* Described below */ 21956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef unsigned int binmap_t; /* Described below */ 21966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef unsigned int flag_t; /* The type of various bit flag sets */ 21976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 21986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------- Chunks sizes and alignments ----------------------- */ 21996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MCHUNK_SIZE (sizeof(mchunk)) 22016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if FOOTERS 22036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) 22046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 22056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CHUNK_OVERHEAD (SIZE_T_SIZE) 22066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 22076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* MMapped chunks need a second word of overhead ... */ 22096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) 22106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ... and additional padding for fake next-chunk at foot */ 22116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) 22126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The smallest size we can malloc is an aligned minimal chunk */ 22146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MIN_CHUNK_SIZE\ 22156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 22166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* conversion from malloc headers to user pointers, and back */ 22186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) 22196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) 22206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* chunk associated with aligned address A */ 22216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) 22226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Bounds on request (not chunk) sizes. */ 22246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) 22256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) 22266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* pad request bytes into a usable size */ 22286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define pad_request(req) \ 22296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 22306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* pad request, checking for minimum (but not maximum) */ 22326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define request2size(req) \ 22336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) 22346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------ Operations on head and foot fields ----------------- */ 22376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 22396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The head field of a chunk is or'ed with PINUSE_BIT when previous 22406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in 22416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao use, unless mmapped, in which case both bits are cleared. 22426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao FLAG4_BIT is not used by this malloc, but might be useful in extensions. 22446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 22456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define PINUSE_BIT (SIZE_T_ONE) 22476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CINUSE_BIT (SIZE_T_TWO) 22486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FLAG4_BIT (SIZE_T_FOUR) 22496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) 22506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) 22516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Head value for fenceposts */ 22536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) 22546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* extraction of fields from head words */ 22566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define cinuse(p) ((p)->head & CINUSE_BIT) 22576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define pinuse(p) ((p)->head & PINUSE_BIT) 22586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define flag4inuse(p) ((p)->head & FLAG4_BIT) 22596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) 22606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) 22616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define chunksize(p) ((p)->head & ~(FLAG_BITS)) 22636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) 22656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_flag4(p) ((p)->head |= FLAG4_BIT) 22666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) 22676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Treat space at ptr +/- offset as a chunk */ 22696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) 22706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) 22716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Ptr to next or previous physical malloc_chunk. */ 22736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) 22746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) 22756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* extract next chunk's pinuse bit */ 22776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) 22786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Get/set size at footer */ 22806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) 22816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) 22826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set size, pinuse bit, and foot */ 22846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_size_and_pinuse_of_free_chunk(p, s)\ 22856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) 22866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set size, pinuse bit, foot, and clear next pinuse */ 22886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_free_with_pinuse(p, s, n)\ 22896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) 22906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Get the internal overhead associated with chunk p */ 22926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define overhead_for(p)\ 22936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) 22946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 22956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Return true if malloced space is not necessarily cleared */ 22966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MMAP_CLEARS 22976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define calloc_must_clear(p) (!is_mmapped(p)) 22986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MMAP_CLEARS */ 22996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define calloc_must_clear(p) (1) 23006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MMAP_CLEARS */ 23016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------- Overlaid data structures ----------------------- */ 23036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 23056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao When chunks are not in use, they are treated as nodes of either 23066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lists or trees. 23076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao "Small" chunks are stored in circular doubly-linked lists, and look 23096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao like this: 23106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of previous chunk | 23136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao `head:' | Size of chunk, in bytes |P| 23156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Forward pointer to next chunk in list | 23176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Back pointer to previous chunk in list | 23196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Unused space (may be 0 bytes long) . 23216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao . . 23226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao . | 23236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaonextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao `foot:' | Size of chunk, in bytes | 23256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Larger chunks are kept in a form of bitwise digital trees (aka 23286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tries) keyed on chunksizes. Because malloc_tree_chunks are only for 23296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free chunks greater than 256 bytes, their size doesn't impose any 23306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao constraints on user chunk sizes. Each node looks like: 23316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Size of previous chunk | 23346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao `head:' | Size of chunk, in bytes |P| 23366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Forward pointer to next chunk of same size | 23386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Back pointer to previous chunk of same size | 23406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Pointer to left child (child[0]) | 23426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Pointer to right child (child[1]) | 23446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Pointer to parent | 23466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | bin index of this chunk | 23486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao | Unused space . 23506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao . | 23516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaonextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao `foot:' | Size of chunk, in bytes | 23536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each tree holding treenodes is a tree of unique chunk sizes. Chunks 23566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of the same size are arranged in a circularly-linked list, with only 23576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the oldest chunk (the next to be used, in our FIFO ordering) 23586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao actually in the tree. (Tree members are distinguished by a non-null 23596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao parent pointer.) If a chunk with the same size an an existing node 23606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is inserted, it is linked off the existing node using pointers that 23616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao work in the same way as fd/bk pointers of small chunks. 23626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each tree contains a power of 2 sized range of chunk sizes (the 23646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao smallest is 0x100 <= x < 0x180), which is is divided in half at each 23656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tree level, with the chunks in the smaller half of the range (0x100 23666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao <= x < 0x140 for the top nose) in the left subtree and the larger 23676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao half (0x140 <= x < 0x180) in the right subtree. This is, of course, 23686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao done by inspecting individual bits. 23696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Using these rules, each node's left subtree contains all smaller 23716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sizes than its right subtree. However, the node at the root of each 23726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao subtree has no particular ordering relationship to either. (The 23736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dividing line between the subtree sizes is based on trie relation.) 23746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If we remove the last chunk of a given size from the interior of the 23756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tree, we need to replace it with a leaf node. The tree ordering 23766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rules permit a node to be replaced by any leaf below it. 23776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The smallest chunk in a tree (a common operation in a best-fit 23796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allocator) can be found by walking a path to the leftmost leaf in 23806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the tree. Unlike a usual binary tree, where we follow left child 23816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointers until we reach a null, here we follow the right child 23826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointer any time the left one is null, until we reach a leaf with 23836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao both child pointers null. The smallest chunk in the tree will be 23846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao somewhere along that path. 23856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The worst case number of steps to add, find, or remove a node is 23876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bounded by the number of bits differentiating chunks within 23886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bins. Under current bin calculations, this ranges from 6 up to 21 23896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case 23906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is of course much better. 23916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 23926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 23936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_tree_chunk { 23946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* The first four fields must be compatible with malloc_chunk */ 23956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t prev_foot; 23966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t head; 23976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_tree_chunk* fd; 23986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_tree_chunk* bk; 23996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_tree_chunk* child[2]; 24016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_tree_chunk* parent; 24026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t index; 24036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 24046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_tree_chunk tchunk; 24066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_tree_chunk* tchunkptr; 24076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ 24086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* A little helper macro for trees */ 24106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) 24116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------------- Segments -------------------------------- */ 24136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 24156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each malloc space may include non-contiguous segments, held in a 24166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao list headed by an embedded malloc_segment record representing the 24176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao top-most space. Segments also include flags holding properties of 24186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the space. Large chunks that are directly allocated by mmap are not 24196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao included in this list. They are instead independently created and 24206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao destroyed without otherwise keeping track of them. 24216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Segment management mainly comes into play for spaces allocated by 24236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MMAP. Any call to MMAP might or might not return memory that is 24246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao adjacent to an existing segment. MORECORE normally contiguously 24256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extends the current space, so this space is almost always adjacent, 24266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao which is simpler and faster to deal with. (This is why MORECORE is 24276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used preferentially to MMAP when both are available -- see 24286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sys_alloc.) When allocating using MMAP, we don't use any of the 24296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao hinting mechanisms (inconsistently) supported in various 24306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao implementations of unix mmap, or distinguish reserving from 24316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao committing memory. Instead, we just ask for space, and exploit 24326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao contiguity when we get it. It is probably possible to do 24336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao better than this on some systems, but no general scheme seems 24346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to be significantly better. 24356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Management entails a simpler variant of the consolidation scheme 24376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used for chunks to reduce fragmentation -- new adjacent memory is 24386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao normally prepended or appended to an existing segment. However, 24396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao there are limitations compared to chunk consolidation that mostly 24406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao reflect the fact that segment processing is relatively infrequent 24416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (occurring only when getting memory from system) and that we 24426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao don't expect to have huge numbers of segments: 24436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Segments are not indexed, so traversal requires linear scans. (It 24456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao would be possible to index these, but is not worth the extra 24466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao overhead and complexity for most programs on most platforms.) 24476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * New segments are only appended to old ones when holding top-most 24486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory; if they cannot be prepended to others, they are held in 24496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao different segments. 24506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Except for the top-most segment of an mstate, each segment record 24526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is kept at the tail of its segment. Segments are added by pushing 24536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao segment records onto the list headed by &mstate.seg for the 24546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao containing mstate. 24556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Segment flags control allocation/merge/deallocation policies: 24576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * If EXTERN_BIT set, then we did not allocate this segment, 24586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and so should not try to deallocate or merge with others. 24596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (This currently holds only for the initial segment passed 24606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao into create_mspace_with_base.) 24616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * If USE_MMAP_BIT set, the segment may be merged with 24626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao other surrounding mmapped segments and trimmed/de-allocated 24636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao using munmap. 24646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * If neither bit is set, then the segment was obtained using 24656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MORECORE so can be merged with surrounding MORECORE'd segments 24666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and deallocated/trimmed using MORECORE with negative arguments. 24676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 24686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_segment { 24706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* base; /* base address */ 24716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size; /* allocated size */ 24726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct malloc_segment* next; /* ptr to next segment */ 24736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t sflags; /* mmap and extern flag */ 24746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 24756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) 24776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) 24786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_segment msegment; 24806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_segment* msegmentptr; 24816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------------- malloc_state ----------------------------- */ 24836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 24856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao A malloc_state holds all of the bookkeeping for a space. 24866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The main fields are: 24876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Top 24896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The topmost chunk of the currently active segment. Its size is 24906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cached in topsize. The actual size of topmost space is 24916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao topsize+TOP_FOOT_SIZE, which includes space reserved for adding 24926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fenceposts and segment records if necessary when getting more 24936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space from the system. The size at which to autotrim top is 24946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cached from mparams in trim_check, except that it is disabled if 24956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao an autotrim fails. 24966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 24976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Designated victim (dv) 24986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao This is the preferred chunk for servicing small requests that 24996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao don't have exact fits. It is normally the chunk split off most 25006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao recently to service another small request. Its size is cached in 25016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dvsize. The link fields of this chunk are not maintained since it 25026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao is not kept in a bin. 25036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SmallBins 25056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao An array of bin headers for free chunks. These bins hold chunks 25066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with sizes less than MIN_LARGE_SIZE bytes. Each bin contains 25076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks of all the same size, spaced 8 bytes apart. To simplify 25086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao use in double-linked lists, each bin header acts as a malloc_chunk 25096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pointing to the real first node, if it exists (else pointing to 25106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao itself). This avoids special-casing for headers. But to avoid 25116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao waste, we allocate only the fd/bk pointers of bins, and then use 25126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao repositioning tricks to treat these as the fields of a chunk. 25136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao TreeBins 25156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Treebins are pointers to the roots of trees holding a range of 25166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sizes. There are 2 equally spaced treebins for each power of two 25176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything 25186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao larger. 25196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Bin maps 25216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao There is one bit map for small bins ("smallmap") and one for 25226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao treebins ("treemap). Each bin sets its bit when non-empty, and 25236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao clears the bit when empty. Bit operations are then used to avoid 25246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bin-by-bin searching -- nearly all "search" is done without ever 25256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao looking at bins that won't be selected. The bit maps 25266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao conservatively use 32 bits per map word, even if on 64bit system. 25276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao For a good description of some of the bit-based techniques used 25286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao here, see Henry S. Warren Jr's book "Hacker's Delight" (and 25296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao supplement at http://hackersdelight.org/). Many of these are 25306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao intended to reduce the branchiness of paths through malloc etc, as 25316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao well as to reduce the number of memory locations read or written. 25326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Segments 25346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao A list of segments headed by an embedded malloc_segment record 25356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao representing the initial space. 25366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Address check support 25386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The least_addr field is the least address ever obtained from 25396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MORECORE or MMAP. Attempted frees and reallocs of any address less 25406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao than this are trapped (unless INSECURE is defined). 25416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Magic tag 25436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao A cross-check field that should always hold same value as mparams.magic. 25446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Max allowed footprint 25466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The maximum allowed bytes to allocate from system (zero means no limit) 25476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Flags 25496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Bits recording whether to use MMAP, locks, or contiguous MORECORE 25506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Statistics 25526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Each space keeps track of current and maximum system memory 25536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao obtained via MORECORE or MMAP. 25546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Trim support 25566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Fields holding the amount of unused topmost memory that should trigger 25576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao trimming, and a counter to force periodic scanning to release unused 25586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao non-topmost segments. 25596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Locking 25616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If USE_LOCKS is defined, the "mutex" lock is acquired and released 25626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao around every public call using this mspace. 25636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Extension support 25656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao A void* pointer and a size_t field that can be used to help implement 25666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extensions to this malloc. 25676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 25686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Bin types, widths and sizes */ 25706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NSMALLBINS (32U) 25716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define NTREEBINS (32U) 25726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SMALLBIN_SHIFT (3U) 25736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) 25746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TREEBIN_SHIFT (8U) 25756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) 25766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) 25776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) 25786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 25796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_state { 25806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t smallmap; 25816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t treemap; 25826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dvsize; 25836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t topsize; 25846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* least_addr; 25856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr dv; 25866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr top; 25876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t trim_check; 25886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t release_checks; 25896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t magic; 25906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr smallbins[(NSMALLBINS+1)*2]; 25916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbinptr treebins[NTREEBINS]; 25926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t footprint; 25936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t max_footprint; 25946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t footprint_limit; /* zero means no limit */ 25956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t mflags; 25966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS 25976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MLOCK_T mutex; /* locate lock among fields that rarely change */ 25986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 25996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegment seg; 26006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* extp; /* Unused but available for extensions */ 26016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t exts; 26026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 26036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaotypedef struct malloc_state* mstate; 26056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------- Global malloc_state and malloc_params ------------------- */ 26076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 26096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_params holds global properties, including those that can be 26106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dynamically set using mallopt. There is a single instance, mparams, 26116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao initialized in init_mparams. Note that the non-zeroness of "magic" 26126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao also serves as an initialization flag. 26136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 26146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct malloc_params { 26166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t magic; 26176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t page_size; 26186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t granularity; 26196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t mmap_threshold; 26206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t trim_threshold; 26216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t default_mflags; 26226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao}; 26236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic struct malloc_params mparams; 26256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Ensure mparams initialized */ 26276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) 26286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 26306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The global malloc_state used for all non-"mspace" calls */ 26326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic struct malloc_state _gm_; 26336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define gm (&_gm_) 26346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_global(M) ((M) == &_gm_) 26356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !ONLY_MSPACES */ 26376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_initialized(M) ((M)->top != 0) 26396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------------- system alloc setup ------------------------- */ 26416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Operations on mflags */ 26436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) 26456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) 26466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS 26476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) 26486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 26496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define disable_lock(M) 26506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 26516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) 26536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) 26546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if HAVE_MMAP 26556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) 26566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 26576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define disable_mmap(M) 26586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 26596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) 26616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) 26626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_lock(M,L)\ 26646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((M)->mflags = (L)?\ 26656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((M)->mflags | USE_LOCK_BIT) :\ 26666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((M)->mflags & ~USE_LOCK_BIT)) 26676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* page-align a size */ 26696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define page_align(S)\ 26706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) 26716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* granularity-align a size */ 26736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define granularity_align(S)\ 26746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((S) + (mparams.granularity - SIZE_T_ONE))\ 26756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao & ~(mparams.granularity - SIZE_T_ONE)) 26766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* For mmap, use granularity alignment on windows, else page-align */ 26796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef WIN32 26806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mmap_align(S) granularity_align(S) 26816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 26826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mmap_align(S) page_align(S) 26836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 26846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* For sys_alloc, enough padding to ensure can malloc request on success */ 26866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) 26876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_page_aligned(S)\ 26896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) 26906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_granularity_aligned(S)\ 26916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) 26926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* True if segment S holds address A */ 26946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define segment_holds(S, A)\ 26956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) 26966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 26976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Return segment holding given address */ 26986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic msegmentptr segment_holding(mstate m, char* addr) { 26996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = &m->seg; 27006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 27016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (addr >= sp->base && addr < sp->base + sp->size) 27026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return sp; 27036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((sp = sp->next) == 0) 27046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 27056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 27066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 27076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Return true if segment contains a segment link */ 27096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int has_segment_link(mstate m, msegmentptr ss) { 27106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = &m->seg; 27116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 27126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) 27136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 27146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((sp = sp->next) == 0) 27156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 27166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 27176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 27186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef MORECORE_CANNOT_TRIM 27206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define should_trim(M,s) ((s) > (M)->trim_check) 27216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MORECORE_CANNOT_TRIM */ 27226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define should_trim(M,s) (0) 27236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MORECORE_CANNOT_TRIM */ 27246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 27266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao TOP_FOOT_SIZE is padding at the end of a segment, including space 27276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao that may be needed to place segment records and fenceposts when new 27286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao noncontiguous segments are added. 27296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 27306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define TOP_FOOT_SIZE\ 27316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) 27326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------------------- Hooks -------------------------------- */ 27356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 27376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao PREACTION should be defined to return 0 on success, and nonzero on 27386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao failure. If you are not using locking, you can redefine these to do 27396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao anything you like. 27406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 27416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS 27436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) 27446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } 27456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* USE_LOCKS */ 27466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef PREACTION 27486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define PREACTION(M) (0) 27496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* PREACTION */ 27506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef POSTACTION 27526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define POSTACTION(M) 27536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* POSTACTION */ 27546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_LOCKS */ 27566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 27586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. 27596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION is triggered on detected bad frees and 27606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao reallocs. The argument p is an address that might have triggered the 27616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fault. It is ignored by the two predefined actions, but might be 27626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao useful in custom actions that try to help diagnose errors. 27636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 27646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if PROCEED_ON_ERROR 27666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* A count of the number of corruption errors causing resets */ 27686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint malloc_corruption_error_count; 27696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* default corruption action */ 27716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void reset_on_error(mstate m); 27726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) 27746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USAGE_ERROR_ACTION(m, p) 27756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* PROCEED_ON_ERROR */ 27776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef CORRUPTION_ERROR_ACTION 27796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define CORRUPTION_ERROR_ACTION(m) ABORT 27806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* CORRUPTION_ERROR_ACTION */ 27816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef USAGE_ERROR_ACTION 27836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define USAGE_ERROR_ACTION(m,p) ABORT 27846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USAGE_ERROR_ACTION */ 27856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* PROCEED_ON_ERROR */ 27876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------------- Debugging setup ---------------------------- */ 27906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ! DEBUG 27926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 27936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_free_chunk(M,P) 27946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_inuse_chunk(M,P) 27956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_malloced_chunk(M,P,N) 27966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_mmapped_chunk(M,P) 27976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_malloc_state(M) 27986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_top_chunk(M,P) 27996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* DEBUG */ 28016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_free_chunk(M,P) do_check_free_chunk(M,P) 28026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) 28036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_top_chunk(M,P) do_check_top_chunk(M,P) 28046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) 28056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) 28066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define check_malloc_state(M) do_check_malloc_state(M) 28076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_any_chunk(mstate m, mchunkptr p); 28096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_top_chunk(mstate m, mchunkptr p); 28106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_mmapped_chunk(mstate m, mchunkptr p); 28116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_inuse_chunk(mstate m, mchunkptr p); 28126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_free_chunk(mstate m, mchunkptr p); 28136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_malloced_chunk(mstate m, void* mem, size_t s); 28146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_tree(mstate m, tchunkptr t); 28156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_treebin(mstate m, bindex_t i); 28166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_smallbin(mstate m, bindex_t i); 28176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_malloc_state(mstate m); 28186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int bin_find(mstate m, mchunkptr x); 28196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic size_t traverse_and_check(mstate m); 28206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEBUG */ 28216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------------- Indexing Bins ---------------------------- */ 28236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) 28256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) 28266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define small_index2size(i) ((i) << SMALLBIN_SHIFT) 28276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) 28286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* addressing by index. See above about smallbin repositioning */ 28306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* BEGIN android-changed: strict aliasing change: char* cast to void* */ 28316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define smallbin_at(M, i) ((sbinptr)((void*)&((M)->smallbins[(i)<<1]))) 28326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* END android-changed */ 28336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define treebin_at(M,i) (&((M)->treebins[i])) 28346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* assign tree index for size S to variable I. Use x86 asm if possible */ 28366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 28376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_tree_index(S, I)\ 28386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 28396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int X = S >> TREEBIN_SHIFT;\ 28406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X == 0)\ 28416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = 0;\ 28426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (X > 0xFFFF)\ 28436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = NTREEBINS-1;\ 28446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 28456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \ 28466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ 28476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 28486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 28496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined (__INTEL_COMPILER) 28516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_tree_index(S, I)\ 28526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 28536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t X = S >> TREEBIN_SHIFT;\ 28546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X == 0)\ 28556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = 0;\ 28566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (X > 0xFFFF)\ 28576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = NTREEBINS-1;\ 28586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 28596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int K = _bit_scan_reverse (X); \ 28606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ 28616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 28626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 28636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(_MSC_VER) && _MSC_VER>=1300 28656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_tree_index(S, I)\ 28666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 28676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t X = S >> TREEBIN_SHIFT;\ 28686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X == 0)\ 28696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = 0;\ 28706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (X > 0xFFFF)\ 28716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = NTREEBINS-1;\ 28726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 28736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int K;\ 28746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao _BitScanReverse((DWORD *) &K, (DWORD) X);\ 28756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ 28766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 28776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 28786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* GNUC */ 28806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_tree_index(S, I)\ 28816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 28826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t X = S >> TREEBIN_SHIFT;\ 28836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X == 0)\ 28846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = 0;\ 28856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (X > 0xFFFF)\ 28866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = NTREEBINS-1;\ 28876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 28886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int Y = (unsigned int)X;\ 28896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int N = ((Y - 0x100) >> 16) & 8;\ 28906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ 28916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K;\ 28926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ 28936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao K = 14 - N + ((Y <<= K) >> 15);\ 28946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ 28956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 28966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 28976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* GNUC */ 28986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 28996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Bit representing maximum resolved size in a treebin at i */ 29006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define bit_for_tree_index(i) \ 29016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) 29026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Shift placing maximum resolved bit in a treebin at i as sign bit */ 29046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define leftshift_for_tree_index(i) \ 29056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((i == NTREEBINS-1)? 0 : \ 29066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) 29076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* The size of the smallest chunk held in bin with index i */ 29096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define minsize_for_tree_index(i) \ 29106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ 29116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) 29126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------------ Operations on bin maps ----------------------- */ 29156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* bit corresponding to given index */ 29176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define idx2bit(i) ((binmap_t)(1) << (i)) 29186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Mark/Clear bits with given index */ 29206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) 29216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) 29226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) 29236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) 29256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) 29266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) 29276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* isolate the least set bit of a bitmap */ 29296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define least_bit(x) ((x) & -(x)) 29306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* mask with all bits to left of least bit of x on */ 29326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define left_bits(x) ((x<<1) | -(x<<1)) 29336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* mask with all bits to left of or equal to least bit of x on */ 29356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define same_or_left_bits(x) ((x) | -(x)) 29366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* index corresponding to given bit. Use x86 asm if possible */ 29386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 29406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_bit2idx(X, I)\ 29416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 29426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int J;\ 29436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao J = __builtin_ctz(X); \ 29446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)J;\ 29456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 29466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined (__INTEL_COMPILER) 29486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_bit2idx(X, I)\ 29496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 29506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int J;\ 29516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao J = _bit_scan_forward (X); \ 29526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)J;\ 29536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 29546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(_MSC_VER) && _MSC_VER>=1300 29566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_bit2idx(X, I)\ 29576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 29586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int J;\ 29596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao _BitScanForward((DWORD *) &J, X);\ 29606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)J;\ 29616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 29626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif USE_BUILTIN_FFS 29646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_bit2idx(X, I) I = ffs(X)-1 29656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 29676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define compute_bit2idx(X, I)\ 29686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao{\ 29696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int Y = X - 1;\ 29706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int K = Y >> (16-4) & 16;\ 29716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int N = K; Y >>= K;\ 29726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K = Y >> (8-3) & 8; Y >>= K;\ 29736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K = Y >> (4-2) & 4; Y >>= K;\ 29746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K = Y >> (2-1) & 2; Y >>= K;\ 29756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao N += K = Y >> (1-0) & 1; Y >>= K;\ 29766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao I = (bindex_t)(N + Y);\ 29776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 29786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* GNUC */ 29796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- Runtime Check Support ------------------------- */ 29826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 29846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao For security, the main invariant is that malloc/free/etc never 29856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao writes to a static address other than malloc_state, unless static 29866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc_state itself has been corrupted, which cannot occur via 29876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc (because of these checks). In essence this means that we 29886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao believe all pointers, sizes, maps etc held in malloc_state, but 29896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check all of those linked or offsetted from other embedded data 29906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao structures. These checks are interspersed with main code in a way 29916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao that tends to minimize their run-time cost. 29926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 29936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao When FOOTERS is defined, in addition to range checking, we also 29946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao verify footer fields of inuse chunks, which can be used guarantee 29956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao that the mstate controlling malloc/free is intact. This is a 29966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao streamlined version of the approach described by William Robertson 29976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao et al in "Run-time Detection of Heap-based Overflows" LISA'03 29986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao http://www.usenix.org/events/lisa03/tech/robertson.html The footer 29996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of an inuse chunk holds the xor of its mstate and a random seed, 30006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao that is checked upon calls to free() and realloc(). This is 30016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (probabalistically) unguessable from outside the program, but can be 30026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao computed by any code successfully malloc'ing any chunk, so does not 30036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao itself provide protection against code that has already broken 30046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao security through some other means. Unlike Robertson et al, we 30056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao always dynamically check addresses of all offset chunks (previous, 30066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao next, etc). This turns out to be cheaper than relying on hashes. 30076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 30086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !INSECURE 30106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check if address a is at least as high as any from MORECORE or MMAP */ 30116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) 30126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check if address of next chunk n is higher than base chunk p */ 30136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_next(p, n) ((char*)(p) < (char*)(n)) 30146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check if p has inuse status */ 30156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_inuse(p) is_inuse(p) 30166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check if p has its pinuse bit on */ 30176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_pinuse(p) pinuse(p) 30186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* !INSECURE */ 30206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_address(M, a) (1) 30216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_next(b, n) (1) 30226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_inuse(p) (1) 30236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_pinuse(p) (1) 30246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !INSECURE */ 30256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if (FOOTERS && !INSECURE) 30276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check if (alleged) mstate m has expected magic field */ 30286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_magic(M) ((M)->magic == mparams.magic) 30296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* (FOOTERS && !INSECURE) */ 30306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define ok_magic(M) (1) 30316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* (FOOTERS && !INSECURE) */ 30326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* In gcc, use __builtin_expect to minimize impact of checks */ 30346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !INSECURE 30356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if defined(__GNUC__) && __GNUC__ >= 3 30366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RTCHECK(e) __builtin_expect(e, 1) 30376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* GNUC */ 30386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RTCHECK(e) (e) 30396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* GNUC */ 30406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* !INSECURE */ 30416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define RTCHECK(e) (1) 30426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !INSECURE */ 30436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* macros to set up inuse chunks with or without footers */ 30456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !FOOTERS 30476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mark_inuse_foot(M,p,s) 30496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Macros for setting head/foot of non-mmapped chunks */ 30516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set cinuse bit and pinuse bit of next chunk */ 30536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_inuse(M,p,s)\ 30546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ 30556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) 30566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ 30586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_inuse_and_pinuse(M,p,s)\ 30596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 30606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) 30616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set size, cinuse and pinuse bit of this chunk */ 30636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ 30646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) 30656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 30676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Set foot of inuse chunk to be xor of mstate and seed */ 30696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define mark_inuse_foot(M,p,s)\ 30706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) 30716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define get_mstate_for(p)\ 30736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((mstate)(((mchunkptr)((char*)(p) +\ 30746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (chunksize(p))))->prev_foot ^ mparams.magic)) 30756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_inuse(M,p,s)\ 30776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ 30786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ 30796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_inuse_foot(M,p,s)) 30806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_inuse_and_pinuse(M,p,s)\ 30826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 30836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ 30846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_inuse_foot(M,p,s)) 30856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ 30876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 30886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_inuse_foot(M, p, s)) 30896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !FOOTERS */ 30916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------------- setting mparams -------------------------- */ 30936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 30946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if LOCK_AT_FORK 30956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void pre_fork(void) { ACQUIRE_LOCK(&(gm)->mutex); } 30966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); } 30976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void post_fork_child(void) { INITIAL_LOCK(&(gm)->mutex); } 30986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* LOCK_AT_FORK */ 30996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Initialize mparams */ 31016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int init_mparams(void) { 31026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-added: move pthread_atfork outside of lock */ 31036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int first_run = 0; 31046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-added */ 31056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef NEED_GLOBAL_LOCK_INIT 31066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (malloc_global_mutex_status <= 0) 31076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_malloc_global_mutex(); 31086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 31096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ACQUIRE_MALLOC_GLOBAL_LOCK(); 31116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mparams.magic == 0) { 31126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t magic; 31136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize; 31146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t gsize; 31156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-added: move pthread_atfork outside of lock */ 31166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao first_run = 1; 31176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-added */ 31186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifndef WIN32 31206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize = malloc_getpagesize; 31216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); 31226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* WIN32 */ 31236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 31246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SYSTEM_INFO system_info; 31256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao GetSystemInfo(&system_info); 31266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize = system_info.dwPageSize; 31276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gsize = ((DEFAULT_GRANULARITY != 0)? 31286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); 31296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 31306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* WIN32 */ 31316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Sanity-check configuration: 31336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t must be unsigned and as wide as pointer type. 31346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ints must be at least 4 bytes. 31356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignment must be at least 8. 31366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Alignment, min chunk size, and page size must all be powers of 2. 31376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 31386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((sizeof(size_t) != sizeof(char*)) || 31396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (MAX_SIZE_T < MIN_CHUNK_SIZE) || 31406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (sizeof(int) < 4) || 31416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (MALLOC_ALIGNMENT < (size_t)8U) || 31426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || 31436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || 31446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((gsize & (gsize-SIZE_T_ONE)) != 0) || 31456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((psize & (psize-SIZE_T_ONE)) != 0)) 31466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ABORT; 31476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.granularity = gsize; 31486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.page_size = psize; 31496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; 31506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; 31516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MORECORE_CONTIGUOUS 31526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; 31536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MORECORE_CONTIGUOUS */ 31546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; 31556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MORECORE_CONTIGUOUS */ 31566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 31586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Set up lock for main malloc area */ 31596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gm->mflags = mparams.default_mflags; 31606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)INITIAL_LOCK(&gm->mutex); 31616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 31626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-removed: move pthread_atfork outside of lock */ 31636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if 0 && LOCK_AT_FORK 31646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); 31656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 31666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-removed */ 31676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 31696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_DEV_RANDOM 31706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int fd; 31716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned char buf[sizeof(size_t)]; 31726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Try to use /dev/urandom, else fall back on using time */ 31736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && 31746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao read(fd, buf, sizeof(buf)) == sizeof(buf)) { 31756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic = *((size_t *) buf); 31766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao close(fd); 31776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 31786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 31796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* USE_DEV_RANDOM */ 31806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef WIN32 31816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); 31826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#elif defined(LACKS_TIME_H) 31836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic = (size_t)&magic ^ (size_t)0x55555555U; 31846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else 31856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic = (size_t)(time(0) ^ (size_t)0x55555555U); 31866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 31876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic |= (size_t)8U; /* ensure nonzero */ 31886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao magic &= ~(size_t)7U; /* improve chances of fault for bad values */ 31896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Until memory modes commonly available, use volatile-write */ 31906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (*(volatile size_t *)(&(mparams.magic))) = magic; 31916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 31926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 31936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 31946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao RELEASE_MALLOC_GLOBAL_LOCK(); 31956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-added: move pthread_atfork outside of lock */ 31966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (first_run != 0) { 31976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if LOCK_AT_FORK 31986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); 31996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 32006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 32016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-added */ 32026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 32036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* support for mallopt */ 32066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int change_mparam(int param_number, int value) { 32076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t val; 32086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 32096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao val = (value == -1)? MAX_SIZE_T : (size_t)value; 32106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao switch(param_number) { 32116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao case M_TRIM_THRESHOLD: 32126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.trim_threshold = val; 32136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 32146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao case M_GRANULARITY: 32156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (val >= mparams.page_size && ((val & (val-1)) == 0)) { 32166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.granularity = val; 32176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 32186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 32196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 32206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 32216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao case M_MMAP_THRESHOLD: 32226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mparams.mmap_threshold = val; 32236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 32246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao default: 32256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 32266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 32276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if DEBUG 32306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------------- Debugging Support --------------------------- */ 32316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of any chunk, whether free, inuse, mmapped etc */ 32336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_any_chunk(mstate m, mchunkptr p) { 32346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 32356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(ok_address(m, p)); 32366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of top chunk */ 32396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_top_chunk(mstate m, mchunkptr p) { 32406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = segment_holding(m, (char*)p); 32416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ 32426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sp != 0); 32436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 32446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(ok_address(m, p)); 32456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz == m->topsize); 32466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz > 0); 32476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); 32486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(pinuse(p)); 32496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!pinuse(chunk_plus_offset(p, sz))); 32506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of (inuse) mmapped chunks */ 32536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_mmapped_chunk(mstate m, mchunkptr p) { 32546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = chunksize(p); 32556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); 32566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_mmapped(p)); 32576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(use_mmap(m)); 32586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 32596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(ok_address(m, p)); 32606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!is_small(sz)); 32616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); 32626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); 32636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); 32646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of inuse chunks */ 32676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_inuse_chunk(mstate m, mchunkptr p) { 32686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_any_chunk(m, p); 32696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_inuse(p)); 32706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(next_pinuse(p)); 32716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* If not pinuse and not mmapped, previous chunk has OK offset */ 32726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); 32736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) 32746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_mmapped_chunk(m, p); 32756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 32776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of free chunks */ 32786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_free_chunk(mstate m, mchunkptr p) { 32796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = chunksize(p); 32806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = chunk_plus_offset(p, sz); 32816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_any_chunk(m, p); 32826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!is_inuse(p)); 32836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!next_pinuse(p)); 32846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert (!is_mmapped(p)); 32856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p != m->dv && p != m->top) { 32866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (sz >= MIN_CHUNK_SIZE) { 32876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((sz & CHUNK_ALIGN_MASK) == 0); 32886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_aligned(chunk2mem(p))); 32896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(next->prev_foot == sz); 32906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(pinuse(p)); 32916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert (next == m->top || is_inuse(next)); 32926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(p->fd->bk == p); 32936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(p->bk->fd == p); 32946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 32956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else /* markers are always of size SIZE_T_SIZE */ 32966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz == SIZE_T_SIZE); 32976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 32986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 32996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 33006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check properties of malloced chunks at the point they are malloced */ 33016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_malloced_chunk(mstate m, void* mem, size_t s) { 33026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 33036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 33046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = p->head & ~INUSE_BITS; 33056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_inuse_chunk(m, p); 33066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((sz & CHUNK_ALIGN_MASK) == 0); 33076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz >= MIN_CHUNK_SIZE); 33086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(sz >= s); 33096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ 33106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); 33116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 33136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 33146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check a tree and its subtrees. */ 33156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_tree(mstate m, tchunkptr t) { 33166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr head = 0; 33176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr u = t; 33186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t tindex = t->index; 33196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = chunksize(t); 33206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t idx; 33216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_tree_index(tsize, idx); 33226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(tindex == idx); 33236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(tsize >= MIN_LARGE_SIZE); 33246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(tsize >= minsize_for_tree_index(idx)); 33256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); 33266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 33276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do { /* traverse through chain of same-sized nodes */ 33286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_any_chunk(m, ((mchunkptr)u)); 33296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->index == tindex); 33306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(u) == tsize); 33316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!is_inuse(u)); 33326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!next_pinuse(u)); 33336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->fd->bk == u); 33346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->bk->fd == u); 33356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (u->parent == 0) { 33366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[0] == 0); 33376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[1] == 0); 33386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 33406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(head == 0); /* only one node on chain has parent */ 33416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao head = u; 33426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->parent != u); 33436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert (u->parent->child[0] == u || 33446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao u->parent->child[1] == u || 33456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *((tbinptr*)(u->parent)) == u); 33466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (u->child[0] != 0) { 33476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[0]->parent == u); 33486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[0] != u); 33496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_tree(m, u->child[0]); 33506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (u->child[1] != 0) { 33526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[1]->parent == u); 33536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(u->child[1] != u); 33546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_tree(m, u->child[1]); 33556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (u->child[0] != 0 && u->child[1] != 0) { 33576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(u->child[0]) < chunksize(u->child[1])); 33586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao u = u->fd; 33616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } while (u != t); 33626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(head != 0); 33636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 33646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 33656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check all the chunks in a treebin. */ 33666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_treebin(mstate m, bindex_t i) { 33676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbinptr* tb = treebin_at(m, i); 33686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr t = *tb; 33696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int empty = (m->treemap & (1U << i)) == 0; 33706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (t == 0) 33716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(empty); 33726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!empty) 33736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_tree(m, t); 33746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 33756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 33766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check all the chunks in a smallbin. */ 33776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_smallbin(mstate m, bindex_t i) { 33786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sbinptr b = smallbin_at(m, i); 33796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = b->bk; 33806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unsigned int empty = (m->smallmap & (1U << i)) == 0; 33816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == b) 33826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(empty); 33836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!empty) { 33846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (; p != b; p = p->bk) { 33856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size = chunksize(p); 33866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q; 33876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* each chunk claims to be free */ 33886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_free_chunk(m, p); 33896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* chunk belongs in bin */ 33906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(small_index(size) == i); 33916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(p->bk == b || chunksize(p->bk) == chunksize(p)); 33926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* chunk is followed by an inuse chunk */ 33936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q = next_chunk(p); 33946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (q->head != FENCEPOST_HEAD) 33956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_inuse_chunk(m, q); 33966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 33986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 33996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Find x in a bin. Used in other check functions. */ 34016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int bin_find(mstate m, mchunkptr x) { 34026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size = chunksize(x); 34036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(size)) { 34046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t sidx = small_index(size); 34056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sbinptr b = smallbin_at(m, sidx); 34066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (smallmap_is_marked(m, sidx)) { 34076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = b; 34086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do { 34096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == x) 34106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 34116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } while ((p = p->fd) != b); 34126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 34156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t tidx; 34166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_tree_index(size, tidx); 34176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (treemap_is_marked(m, tidx)) { 34186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr t = *treebin_at(m, tidx); 34196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sizebits = size << leftshift_for_tree_index(tidx); 34206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (t != 0 && chunksize(t) != size) { 34216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; 34226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sizebits <<= 1; 34236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (t != 0) { 34256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr u = t; 34266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do { 34276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (u == (tchunkptr)x) 34286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 1; 34296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } while ((u = u->fd) != t); 34306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 34346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 34356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Traverse each chunk and check it; return total */ 34376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic size_t traverse_and_check(mstate m) { 34386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sum = 0; 34396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_initialized(m)) { 34406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr s = &m->seg; 34416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sum += m->topsize + TOP_FOOT_SIZE; 34426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (s != 0) { 34436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = align_as_chunk(s->base); 34446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr lastq = 0; 34456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(pinuse(q)); 34466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (segment_holds(s, q) && 34476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q != m->top && q->head != FENCEPOST_HEAD) { 34486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sum += chunksize(q); 34496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_inuse(q)) { 34506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!bin_find(m, q)); 34516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_inuse_chunk(m, q); 34526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 34546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(q == m->dv || bin_find(m, q)); 34556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ 34566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_free_chunk(m, q); 34576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao lastq = q; 34596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q = next_chunk(q); 34606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao s = s->next; 34626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return sum; 34656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 34666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Check all properties of malloc_state. */ 34696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void do_check_malloc_state(mstate m) { 34706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 34716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t total; 34726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* check bins */ 34736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i < NSMALLBINS; ++i) 34746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_smallbin(m, i); 34756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i < NTREEBINS; ++i) 34766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_treebin(m, i); 34776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->dvsize != 0) { /* check dv chunk */ 34796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_any_chunk(m, m->dv); 34806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(m->dvsize == chunksize(m->dv)); 34816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(m->dvsize >= MIN_CHUNK_SIZE); 34826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(bin_find(m, m->dv) == 0); 34836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->top != 0) { /* check top chunk */ 34866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao do_check_top_chunk(m, m->top); 34876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /*assert(m->topsize == chunksize(m->top)); redundant */ 34886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(m->topsize > 0); 34896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(bin_find(m, m->top) == 0); 34906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 34916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao total = traverse_and_check(m); 34936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(total <= m->footprint); 34946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(m->footprint <= m->max_footprint); 34956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 34966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEBUG */ 34976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 34986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------------- statistics ------------------------------ */ 34996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 35016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic struct mallinfo internal_mallinfo(mstate m) { 35026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 35036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 35046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 35056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloc_state(m); 35066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_initialized(m)) { 35076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nfree = SIZE_T_ONE; /* top always free */ 35086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t mfree = m->topsize + TOP_FOOT_SIZE; 35096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sum = mfree; 35106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr s = &m->seg; 35116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (s != 0) { 35126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = align_as_chunk(s->base); 35136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (segment_holds(s, q) && 35146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q != m->top && q->head != FENCEPOST_HEAD) { 35156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = chunksize(q); 35166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sum += sz; 35176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_inuse(q)) { 35186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mfree += sz; 35196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++nfree; 35206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q = next_chunk(q); 35226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao s = s->next; 35246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.arena = sum; 35276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.ordblks = nfree; 35286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.hblkhd = m->footprint - sum; 35296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-changed: usmblks set to footprint from max_footprint */ 35306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.usmblks = m->footprint; 35316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-changed */ 35326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.uordblks = m->footprint - mfree; 35336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.fordblks = mfree; 35346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nm.keepcost = m->topsize; 35356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 35386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return nm; 35406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 35416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !NO_MALLINFO */ 35426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLOC_STATS 35446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void internal_malloc_stats(mstate m) { 35456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 35466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 35476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t maxfp = 0; 35486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t fp = 0; 35496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used = 0; 35506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloc_state(m); 35516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_initialized(m)) { 35526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr s = &m->seg; 35536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao maxfp = m->max_footprint; 35546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fp = m->footprint; 35556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used = fp - (m->topsize + TOP_FOOT_SIZE); 35566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (s != 0) { 35586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = align_as_chunk(s->base); 35596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (segment_holds(s, q) && 35606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q != m->top && q->head != FENCEPOST_HEAD) { 35616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_inuse(q)) 35626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used -= chunksize(q); 35636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q = next_chunk(q); 35646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao s = s->next; 35666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); /* drop lock */ 35696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); 35706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); 35716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); 35726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 35736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 35746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLOC_STATS */ 35756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- Operations on smallbins ----------------------- */ 35776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 35796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Various forms of linking and unlinking are defined as macros. Even 35806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the ones for trees, which are very long but have very short typical 35816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao paths. This is ugly but reduces reliance on inlining support of 35826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compilers. 35836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 35846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 35856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Link a free chunk into a smallbin */ 35866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define insert_small_chunk(M, P, S) {\ 35876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t I = small_index(S);\ 35886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr B = smallbin_at(M, I);\ 35896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr F = B;\ 35906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(S >= MIN_CHUNK_SIZE);\ 35916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!smallmap_is_marked(M, I))\ 35926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_smallmap(M, I);\ 35936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (RTCHECK(ok_address(M, B->fd)))\ 35946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao F = B->fd;\ 35956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 35966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 35976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 35986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao B->fd = P;\ 35996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao F->bk = P;\ 36006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao P->fd = F;\ 36016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao P->bk = B;\ 36026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 36036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 36046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Unlink a chunk from a smallbin */ 36056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define unlink_small_chunk(M, P, S) {\ 36066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr F = P->fd;\ 36076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr B = P->bk;\ 36086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t I = small_index(S);\ 36096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(P != B);\ 36106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(P != F);\ 36116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(P) == small_index2size(I));\ 36126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \ 36136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (B == F) {\ 36146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao clear_smallmap(M, I);\ 36156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (RTCHECK(B == smallbin_at(M,I) ||\ 36176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (ok_address(M, B) && B->fd == P))) {\ 36186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao F->bk = B;\ 36196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao B->fd = F;\ 36206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 36236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 36276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 36296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 36306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Unlink the first chunk from a smallbin */ 36316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define unlink_first_small_chunk(M, B, P, I) {\ 36326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr F = P->fd;\ 36336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(P != B);\ 36346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(P != F);\ 36356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(P) == small_index2size(I));\ 36366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (B == F) {\ 36376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao clear_smallmap(M, I);\ 36386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\ 36406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao F->bk = B;\ 36416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao B->fd = F;\ 36426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 36456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 36476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 36486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Replace dv node, binning the old one */ 36496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Used only when dvsize known to be small */ 36506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define replace_dv(M, P, S) {\ 36516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t DVS = M->dvsize;\ 36526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_small(DVS));\ 36536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (DVS != 0) {\ 36546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr DV = M->dv;\ 36556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_small_chunk(M, DV, DVS);\ 36566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao M->dvsize = S;\ 36586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao M->dv = P;\ 36596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 36606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 36616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------------- Operations on trees ------------------------- */ 36626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 36636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Insert chunk into tree */ 36646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define insert_large_chunk(M, X, S) {\ 36656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbinptr* H;\ 36666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t I;\ 36676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_tree_index(S, I);\ 36686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao H = treebin_at(M, I);\ 36696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->index = I;\ 36706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->child[0] = X->child[1] = 0;\ 36716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!treemap_is_marked(M, I)) {\ 36726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_treemap(M, I);\ 36736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *H = X;\ 36746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->parent = (tchunkptr)H;\ 36756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->fd = X->bk = X;\ 36766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr T = *H;\ 36796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t K = S << leftshift_for_tree_index(I);\ 36806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) {\ 36816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (chunksize(T) != S) {\ 36826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ 36836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao K <<= 1;\ 36846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (*C != 0)\ 36856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao T = *C;\ 36866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (RTCHECK(ok_address(M, C))) {\ 36876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *C = X;\ 36886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->parent = T;\ 36896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->fd = X->bk = X;\ 36906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break;\ 36916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 36946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break;\ 36956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 36976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 36986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr F = T->fd;\ 36996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ 37006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao T->fd = F->bk = X;\ 37016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->fd = F;\ 37026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->bk = T;\ 37036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao X->parent = 0;\ 37046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break;\ 37056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 37076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break;\ 37096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 37146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 37156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 37166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Unlink steps: 37176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 37186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1. If x is a chained node, unlink it from its same-sized fd/bk links 37196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and choose its bk node as its replacement. 37206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2. If x was the last node of its size, but not a leaf node, it must 37216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao be replaced with a leaf node (not merely one with an open left or 37226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao right), to make sure that lefts and rights of descendents 37236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao correspond properly to bit masks. We use the rightmost descendent 37246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of x. We could use any other leaf, but this is easy to locate and 37256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tends to counteract removal of leftmosts elsewhere, and so keeps 37266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao paths shorter than minimally guaranteed. This doesn't loop much 37276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao because on average a node in a tree is near the bottom. 37286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3. If x is the base of a chain (i.e., has parent links) relink 37296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao x's parent and children to x's replacement (or null if none). 37306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 37316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 37326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define unlink_large_chunk(M, X) {\ 37336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr XP = X->parent;\ 37346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr R;\ 37356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X->bk != X) {\ 37366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr F = X->fd;\ 37376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R = X->bk;\ 37386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\ 37396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao F->bk = R;\ 37406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R->fd = F;\ 37416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 37436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 37476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr* RP;\ 37486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (((R = *(RP = &(X->child[1]))) != 0) ||\ 37496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((R = *(RP = &(X->child[0]))) != 0)) {\ 37506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr* CP;\ 37516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while ((*(CP = &(R->child[1])) != 0) ||\ 37526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (*(CP = &(R->child[0])) != 0)) {\ 37536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R = *(RP = CP);\ 37546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, RP)))\ 37566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *RP = 0;\ 37576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else {\ 37586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (XP != 0) {\ 37636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbinptr* H = treebin_at(M, X->index);\ 37646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (X == *H) {\ 37656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((*H = R) == 0) \ 37666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao clear_treemap(M, X->index);\ 37676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (RTCHECK(ok_address(M, XP))) {\ 37696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (XP->child[0] == X) \ 37706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao XP->child[0] = R;\ 37716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else \ 37726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao XP->child[1] = R;\ 37736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else\ 37756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (R != 0) {\ 37776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, R))) {\ 37786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr C0, C1;\ 37796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R->parent = XP;\ 37806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((C0 = X->child[0]) != 0) {\ 37816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, C0))) {\ 37826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R->child[0] = C0;\ 37836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao C0->parent = R;\ 37846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else\ 37866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((C1 = X->child[1]) != 0) {\ 37896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(M, C1))) {\ 37906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao R->child[1] = C1;\ 37916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao C1->parent = R;\ 37926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else\ 37946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 37976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else\ 37986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(M);\ 37996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 38006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao }\ 38016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 38026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Relays to large vs small bin operations */ 38046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define insert_chunk(M, P, S)\ 38066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(S)) insert_small_chunk(M, P, S)\ 38076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } 38086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define unlink_chunk(M, P, S)\ 38106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(S)) unlink_small_chunk(M, P, S)\ 38116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } 38126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Relays to internal calls to malloc/free from realloc, memalign etc */ 38156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ONLY_MSPACES 38176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_malloc(m, b) mspace_malloc(m, b) 38186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_free(m, mem) mspace_free(m,mem); 38196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* ONLY_MSPACES */ 38206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MSPACES 38216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_malloc(m, b)\ 38226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ((m == gm)? dlmalloc(b) : mspace_malloc(m, b)) 38236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_free(m, mem)\ 38246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m == gm) dlfree(mem); else mspace_free(m,mem); 38256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* MSPACES */ 38266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_malloc(m, b) dlmalloc(b) 38276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define internal_free(m, mem) dlfree(mem) 38286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MSPACES */ 38296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* ONLY_MSPACES */ 38306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- Direct-mmapping chunks ----------------------- */ 38326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 38346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Directly mmapped chunks are set up with an offset to the start of 38356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the mmapped region stored in the prev_foot field of the chunk. This 38366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao allows reconstruction of the required argument to MUNMAP when freed, 38376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and also allows adjustment of the returned chunk to meet alignment 38386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao requirements (especially in memalign). 38396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 38406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Malloc using mmap */ 38426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* mmap_alloc(mstate m, size_t nb) { 38436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); 38446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->footprint_limit != 0) { 38456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t fp = m->footprint + mmsize; 38466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (fp <= m->footprint || fp > m->footprint_limit) 38476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 38486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 38496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mmsize > nb) { /* Check for wrap around 0 */ 38506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); 38516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mm != CMFAIL) { 38526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t offset = align_offset(chunk2mem(mm)); 38536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = mmsize - offset - MMAP_FOOT_PAD; 38546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = (mchunkptr)(mm + offset); 38556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->prev_foot = offset; 38566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = psize; 38576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_inuse_foot(m, p, psize); 38586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; 38596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; 38606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->least_addr == 0 || mm < m->least_addr) 38626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->least_addr = mm; 38636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((m->footprint += mmsize) > m->max_footprint) 38646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->max_footprint = m->footprint; 38656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_aligned(chunk2mem(p))); 38666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_mmapped_chunk(m, p); 38676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunk2mem(p); 38686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 38696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 38706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 38716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 38726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Realloc using mmap */ 38746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { 38756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t oldsize = chunksize(oldp); 38766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)flags; /* placate people compiling -Wunused */ 38776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(nb)) /* Can't shrink mmap regions below small size */ 38786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 38796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Keep old chunk if big enough but not too big */ 38806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldsize >= nb + SIZE_T_SIZE && 38816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (oldsize - nb) <= (mparams.granularity << 1)) 38826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return oldp; 38836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 38846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t offset = oldp->prev_foot; 38856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; 38866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); 38876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* cp = (char*)CALL_MREMAP((char*)oldp - offset, 38886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao oldmmsize, newmmsize, flags); 38896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (cp != CMFAIL) { 38906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = (mchunkptr)(cp + offset); 38916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = newmmsize - offset - MMAP_FOOT_PAD; 38926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp->head = psize; 38936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mark_inuse_foot(m, newp, psize); 38946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; 38956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; 38966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 38976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (cp < m->least_addr) 38986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->least_addr = cp; 38996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) 39006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->max_footprint = m->footprint; 39016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_mmapped_chunk(m, newp); 39026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return newp; 39036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 39066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 39076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------------- mspace management -------------------------- */ 39106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Initialize top chunk and its size */ 39126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void init_top(mstate m, mchunkptr p, size_t psize) { 39136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Ensure alignment */ 39146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t offset = align_offset(chunk2mem(p)); 39156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = (mchunkptr)((char*)p + offset); 39166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize -= offset; 39176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->top = p; 39196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->topsize = psize; 39206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = psize | PINUSE_BIT; 39216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* set size of fake trailing chunk holding overhead space only once */ 39226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; 39236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->trim_check = mparams.trim_threshold; /* reset on each update */ 39246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 39256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Initialize bins for a new mstate that is otherwise zeroed out */ 39276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void init_bins(mstate m) { 39286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Establish circular links for smallbins */ 39296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 39306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i < NSMALLBINS; ++i) { 39316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sbinptr bin = smallbin_at(m,i); 39326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bin->fd = bin->bk = bin; 39336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 39356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if PROCEED_ON_ERROR 39376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* default corruption action */ 39396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void reset_on_error(mstate m) { 39406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int i; 39416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++malloc_corruption_error_count; 39426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Reinitialize fields to forget about all memory */ 39436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->smallmap = m->treemap = 0; 39446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = m->topsize = 0; 39456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.base = 0; 39466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.size = 0; 39476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.next = 0; 39486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->top = m->dv = 0; 39496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i < NTREEBINS; ++i) 39506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *treebin_at(m, i) = 0; 39516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_bins(m); 39526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 39536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* PROCEED_ON_ERROR */ 39546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Allocate chunk and prepend remainder with chunk in successor base. */ 39566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* prepend_alloc(mstate m, char* newbase, char* oldbase, 39576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb) { 39586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = align_as_chunk(newbase); 39596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr oldfirst = align_as_chunk(oldbase); 39606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = (char*)oldfirst - (char*)p; 39616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = chunk_plus_offset(p, nb); 39626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t qsize = psize - nb; 39636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, p, nb); 39646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert((char*)oldfirst > (char*)q); 39666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(pinuse(oldfirst)); 39676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(qsize >= MIN_CHUNK_SIZE); 39686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* consolidate remainder with first chunk of old base */ 39706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldfirst == m->top) { 39716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = m->topsize += qsize; 39726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->top = q; 39736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q->head = tsize | PINUSE_BIT; 39746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(m, q); 39756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (oldfirst == m->dv) { 39776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dsize = m->dvsize += qsize; 39786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = q; 39796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(q, dsize); 39806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 39826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_inuse(oldfirst)) { 39836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nsize = chunksize(oldfirst); 39846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(m, oldfirst, nsize); 39856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao oldfirst = chunk_plus_offset(oldfirst, nsize); 39866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao qsize += nsize; 39876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(q, qsize, oldfirst); 39896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_chunk(m, q, qsize); 39906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_free_chunk(m, q); 39916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 39926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(m, chunk2mem(p), nb); 39946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunk2mem(p); 39956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 39966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 39976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Add a segment to hold a new noncontiguous region */ 39986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { 39996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Determine locations and sizes of segment, fenceposts, old top */ 40006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* old_top = (char*)m->top; 40016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr oldsp = segment_holding(m, old_top); 40026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* old_end = oldsp->base + oldsp->size; 40036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t ssize = pad_request(sizeof(struct malloc_segment)); 40046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); 40056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t offset = align_offset(chunk2mem(rawsp)); 40066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* asp = rawsp + offset; 40076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; 40086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr sp = (mchunkptr)csp; 40096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr ss = (msegmentptr)(chunk2mem(sp)); 40106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr tnext = chunk_plus_offset(sp, ssize); 40116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = tnext; 40126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int nfences = 0; 40136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* reset top to new space */ 40156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); 40166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Set up segment record */ 40186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(is_aligned(ss)); 40196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); 40206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *ss = m->seg; /* Push current record */ 40216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.base = tbase; 40226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.size = tsize; 40236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.sflags = mmapped; 40246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.next = ss; 40256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Insert trailing fenceposts */ 40276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 40286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); 40296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = FENCEPOST_HEAD; 40306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++nfences; 40316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((char*)(&(nextp->head)) < old_end) 40326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = nextp; 40336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 40346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 40356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(nfences >= 2); 40376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Insert the rest of old top into a bin as an ordinary free chunk */ 40396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (csp != old_top) { 40406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = (mchunkptr)old_top; 40416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = csp - old_top; 40426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr tn = chunk_plus_offset(q, psize); 40436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(q, psize, tn); 40446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_chunk(m, q, psize); 40456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(m, m->top); 40486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 40496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------------- System allocation -------------------------- */ 40516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Get memory from system using MORECORE or MMAP */ 40536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* sys_alloc(mstate m, size_t nb) { 40546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* tbase = CMFAIL; 40556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = 0; 40566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t mmap_flag = 0; 40576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t asize; /* allocation size */ 40586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 40606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Directly map large chunks, but only if already initialized */ 40626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { 40636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = mmap_alloc(m, nb); 40646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) 40656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 40666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao asize = granularity_align(nb + SYS_ALLOC_PADDING); 40696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (asize <= nb) { 40706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-added: set errno */ 40716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 40726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-added */ 40736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; /* wraparound */ 40746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->footprint_limit != 0) { 40766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t fp = m->footprint + asize; 40776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (fp <= m->footprint || fp > m->footprint_limit) { 40786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* BEGIN android-added: set errno */ 40796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 40806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* END android-added */ 40816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 40826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 40846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 40856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* 40866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Try getting memory in any of three ways (in most-preferred to 40876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao least-preferred order): 40886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1. A call to MORECORE that can normally contiguously extend memory. 40896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or 40906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao or main space is mmapped or a previous contiguous call failed) 40916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2. A call to MMAP new space (disabled if not HAVE_MMAP). 40926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note that under the default settings, if MORECORE is unable to 40936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fulfill a request, and HAVE_MMAP is true, then mmap is 40946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used as a noncontiguous system allocator. This is a useful backup 40956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao strategy for systems with holes in address spaces -- in this case 40966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sbrk cannot contiguously expand the heap, but mmap may be able to 40976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao find space. 40986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3. A call to MORECORE that cannot usually contiguously extend memory. 40996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (disabled if not HAVE_MORECORE) 41006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao In all cases, we need to request enough bytes from system to ensure 41026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao we can malloc nb bytes upon success, so pad with enough space for 41036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao top_foot, plus alignment-pad to make sure we don't lose bytes if 41046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao not on boundary, and round this up to a granularity unit. 41056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 41066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { 41086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* br = CMFAIL; 41096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t ssize = asize; /* sbrk call size */ 41106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); 41116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ACQUIRE_MALLOC_GLOBAL_LOCK(); 41126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ss == 0) { /* First time through or recovery */ 41146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* base = (char*)CALL_MORECORE(0); 41156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (base != CMFAIL) { 41166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t fp; 41176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Adjust to end on a page boundary */ 41186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_page_aligned(base)) 41196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ssize += (page_align((size_t)base) - (size_t)base); 41206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fp = m->footprint + ssize; /* recheck limits */ 41216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ssize > nb && ssize < HALF_MAX_SIZE_T && 41226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (m->footprint_limit == 0 || 41236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (fp > m->footprint && fp <= m->footprint_limit)) && 41246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (br = (char*)(CALL_MORECORE(ssize))) == base) { 41256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbase = base; 41266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tsize = ssize; 41276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 41316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Subtract out existing available top space from MORECORE request. */ 41326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); 41336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Use mem here only if it did continuously extend old space */ 41346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ssize < HALF_MAX_SIZE_T && 41356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) { 41366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbase = br; 41376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tsize = ssize; 41386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (tbase == CMFAIL) { /* Cope with partial failure */ 41426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (br != CMFAIL) { /* Try to use/extend the space we did get */ 41436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ssize < HALF_MAX_SIZE_T && 41446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ssize < nb + SYS_ALLOC_PADDING) { 41456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize); 41466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (esize < HALF_MAX_SIZE_T) { 41476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* end = (char*)CALL_MORECORE(esize); 41486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (end != CMFAIL) 41496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ssize += esize; 41506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* Can't use; try to release */ 41516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void) CALL_MORECORE(-ssize); 41526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao br = CMFAIL; 41536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (br != CMFAIL) { /* Use the space we did get */ 41586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbase = br; 41596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tsize = ssize; 41606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 41626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable_contiguous(m); /* Don't try contiguous path in the future */ 41636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao RELEASE_MALLOC_GLOBAL_LOCK(); 41666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ 41696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* mp = (char*)(CALL_MMAP(asize)); 41706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mp != CMFAIL) { 41716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbase = mp; 41726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tsize = asize; 41736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mmap_flag = USE_MMAP_BIT; 41746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ 41786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (asize < HALF_MAX_SIZE_T) { 41796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* br = CMFAIL; 41806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* end = CMFAIL; 41816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ACQUIRE_MALLOC_GLOBAL_LOCK(); 41826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao br = (char*)(CALL_MORECORE(asize)); 41836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao end = (char*)(CALL_MORECORE(0)); 41846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao RELEASE_MALLOC_GLOBAL_LOCK(); 41856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (br != CMFAIL && end != CMFAIL && br < end) { 41866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t ssize = end - br; 41876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ssize > nb + TOP_FOOT_SIZE) { 41886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tbase = br; 41896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tsize = ssize; 41906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 41946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (tbase != CMFAIL) { 41966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 41976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((m->footprint += tsize) > m->max_footprint) 41986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->max_footprint = m->footprint; 41996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_initialized(m)) { /* first-time initialization */ 42016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->least_addr == 0 || tbase < m->least_addr) 42026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->least_addr = tbase; 42036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.base = tbase; 42046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.size = tsize; 42056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.sflags = mmap_flag; 42066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->magic = mparams.magic; 42076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->release_checks = MAX_RELEASE_CHECK_RATE; 42086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_bins(m); 42096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 42106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_global(m)) 42116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); 42126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 42136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 42146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 42156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Offset top by embedded malloc_state */ 42166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr mn = next_chunk(mem2chunk(m)); 42176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); 42186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 42226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Try to merge with an existing segment */ 42236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = &m->seg; 42246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Only consider most recent segment if traversal suppressed */ 42256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (sp != 0 && tbase != sp->base + sp->size) 42266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; 42276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (sp != 0 && 42286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao !is_extern_segment(sp) && 42296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (sp->sflags & USE_MMAP_BIT) == mmap_flag && 42306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao segment_holds(sp, m->top)) { /* append */ 42316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->size += tsize; 42326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, m->top, m->topsize + tsize); 42336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 42356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (tbase < m->least_addr) 42366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->least_addr = tbase; 42376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = &m->seg; 42386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (sp != 0 && sp->base != tbase + tsize) 42396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; 42406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (sp != 0 && 42416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao !is_extern_segment(sp) && 42426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (sp->sflags & USE_MMAP_BIT) == mmap_flag) { 42436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* oldbase = sp->base; 42446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->base = tbase; 42456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->size += tsize; 42466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return prepend_alloc(m, tbase, oldbase, nb); 42476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 42496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao add_segment(m, tbase, tsize, mmap_flag); 42506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (nb < m->topsize) { /* Allocate from new or extended top space */ 42546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = m->topsize -= nb; 42556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = m->top; 42566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = m->top = chunk_plus_offset(p, nb); 42576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao r->head = rsize | PINUSE_BIT; 42586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, p, nb); 42596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(m, m->top); 42606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(m, chunk2mem(p), nb); 42616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunk2mem(p); 42626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 42666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 42676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 42686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------- system deallocation -------------------------- */ 42706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 42716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Unmap and unlink any mmapped segments that don't contain used chunks */ 42726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic size_t release_unused_segments(mstate m) { 42736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t released = 0; 42746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int nsegs = 0; 42756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr pred = &m->seg; 42766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = pred->next; 42776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (sp != 0) { 42786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* base = sp->base; 42796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size = sp->size; 42806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr next = sp->next; 42816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++nsegs; 42826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { 42836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = align_as_chunk(base); 42846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = chunksize(p); 42856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Can unmap if first chunk holds entire segment and not pinned */ 42866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { 42876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr tp = (tchunkptr)p; 42886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(segment_holds(sp, (char*)sp)); 42896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == m->dv) { 42906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = 0; 42916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = 0; 42926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 42946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_large_chunk(m, tp); 42956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 42966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (CALL_MUNMAP(base, size) == 0) { 42976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao released += size; 42986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->footprint -= size; 42996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* unlink obsoleted record */ 43006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = pred; 43016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->next = next; 43026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* back out if cannot unmap */ 43046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_large_chunk(m, tp, psize); 43056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ 43096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 43106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pred = sp; 43116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = next; 43126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Reset check counter */ 43146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)? 43156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE); 43166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return released; 43176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 43186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic int sys_trim(mstate m, size_t pad) { 43206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t released = 0; 43216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 43226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (pad < MAX_REQUEST && is_initialized(m)) { 43236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ 43246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m->topsize > pad) { 43266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Shrink top space in granularity-size units, keeping at least one */ 43276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t unit = mparams.granularity; 43286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - 43296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SIZE_T_ONE) * unit; 43306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = segment_holding(m, (char*)m->top); 43316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_extern_segment(sp)) { 43336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped_segment(sp)) { 43346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (HAVE_MMAP && 43356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->size >= extra && 43366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao !has_segment_link(m, sp)) { /* can't shrink if pinned */ 43376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = sp->size - extra; 43386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)newsize; /* placate people compiling -Wunused-variable */ 43396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Prefer mremap, fall back to munmap */ 43406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || 43416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { 43426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao released = extra; 43436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (HAVE_MORECORE) { 43476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ 43486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; 43496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ACQUIRE_MALLOC_GLOBAL_LOCK(); 43506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 43516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Make sure end of memory is where we last set it. */ 43526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* old_br = (char*)(CALL_MORECORE(0)); 43536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (old_br == sp->base + sp->size) { 43546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* rel_br = (char*)(CALL_MORECORE(-extra)); 43556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* new_br = (char*)(CALL_MORECORE(0)); 43566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rel_br != CMFAIL && new_br < old_br) 43576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao released = old_br - new_br; 43586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao RELEASE_MALLOC_GLOBAL_LOCK(); 43616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (released != 0) { 43656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp->size -= released; 43666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->footprint -= released; 43676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, m->top, m->topsize - released); 43686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(m, m->top); 43696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Unmap any unused mmapped segments */ 43736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (HAVE_MMAP) 43746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao released += release_unused_segments(m); 43756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* On failure, disable autotrim to avoid repeated failed future calls */ 43776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (released == 0 && m->topsize > m->trim_check) 43786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->trim_check = MAX_SIZE_T; 43796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (released != 0)? 1 : 0; 43826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 43836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 43846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Consolidate and bin a chunk. Differs from exported versions 43856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao of free mainly in that the chunk need not be marked as inuse. 43866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 43876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void dispose_chunk(mstate m, mchunkptr p, size_t psize) { 43886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = chunk_plus_offset(p, psize); 43896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!pinuse(p)) { 43906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr prev; 43916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t prevsize = p->prev_foot; 43926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) { 43936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize + MMAP_FOOT_PAD; 43946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) 43956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->footprint -= psize; 43966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 43976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 43986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao prev = chunk_minus_offset(p, prevsize); 43996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize; 44006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = prev; 44016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ 44026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p != m->dv) { 44036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(m, p, prevsize); 44046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if ((next->head & INUSE_BITS) == INUSE_BITS) { 44066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = psize; 44076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 44086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 44096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 44126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(m); 44136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 44146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, next))) { 44176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!cinuse(next)) { /* consolidate forward */ 44186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (next == m->top) { 44196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = m->topsize += psize; 44206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->top = p; 44216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = tsize | PINUSE_BIT; 44226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == m->dv) { 44236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = 0; 44246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = 0; 44256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 44276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (next == m->dv) { 44296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dsize = m->dvsize += psize; 44306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = p; 44316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, dsize); 44326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 44336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 44356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nsize = chunksize(next); 44366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += nsize; 44376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(m, next, nsize); 44386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, psize); 44396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == m->dv) { 44406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = psize; 44416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 44426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 44466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 44476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_chunk(m, p, psize); 44496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 44516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(m); 44526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 44546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 44556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------------- malloc --------------------------- */ 44566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 44576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* allocate a large request from the best fitting chunk in a treebin */ 44586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* tmalloc_large(mstate m, size_t nb) { 44596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr v = 0; 44606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = -nb; /* Unsigned negation */ 44616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr t; 44626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t idx; 44636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_tree_index(nb, idx); 44646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((t = *treebin_at(m, idx)) != 0) { 44656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Traverse tree for this bin looking for node with size == nb */ 44666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sizebits = nb << leftshift_for_tree_index(idx); 44676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr rst = 0; /* The deepest untaken right subtree */ 44686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (;;) { 44696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr rt; 44706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t trem = chunksize(t) - nb; 44716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (trem < rsize) { 44726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v = t; 44736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((rsize = trem) == 0) 44746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 44756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rt = t->child[1]; 44776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; 44786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rt != 0 && rt != t) 44796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rst = rt; 44806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (t == 0) { 44816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao t = rst; /* set t to least subtree holding sizes > nb */ 44826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 44836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sizebits <<= 1; 44856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ 44886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; 44896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (leftbits != 0) { 44906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 44916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leastbit = least_bit(leftbits); 44926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_bit2idx(leastbit, i); 44936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao t = *treebin_at(m, i); 44946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 44966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 44976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (t != 0) { /* find smallest of tree or subtree */ 44986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t trem = chunksize(t) - nb; 44996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (trem < rsize) { 45006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rsize = trem; 45016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v = t; 45026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao t = leftmost_child(t); 45046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* If dv is a better fit, return 0 so malloc will use it */ 45076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { 45086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, v))) { /* split */ 45096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = chunk_plus_offset(v, nb); 45106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(v) == rsize + nb); 45116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_next(v, r))) { 45126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_large_chunk(m, v); 45136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize < MIN_CHUNK_SIZE) 45146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(m, v, (rsize + nb)); 45156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 45166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, v, nb); 45176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 45186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_chunk(m, r, rsize); 45196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunk2mem(v); 45216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(m); 45246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 45266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 45276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* allocate a small request from the best fitting chunk in a treebin */ 45296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* tmalloc_small(mstate m, size_t nb) { 45306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr t, v; 45316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize; 45326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 45336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leastbit = least_bit(m->treemap); 45346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_bit2idx(leastbit, i); 45356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v = t = *treebin_at(m, i); 45366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rsize = chunksize(t) - nb; 45376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while ((t = leftmost_child(t)) != 0) { 45396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t trem = chunksize(t) - nb; 45406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (trem < rsize) { 45416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rsize = trem; 45426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v = t; 45436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, v))) { 45476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = chunk_plus_offset(v, nb); 45486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(v) == rsize + nb); 45496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_next(v, r))) { 45506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_large_chunk(m, v); 45516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize < MIN_CHUNK_SIZE) 45526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(m, v, (rsize + nb)); 45536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 45546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, v, nb); 45556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 45566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao replace_dv(m, r, rsize); 45576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunk2mem(v); 45596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 45616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(m); 45636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 45646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 45656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 45676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlmalloc(size_t bytes) { 45696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* 45706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Basic algorithm: 45716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao If a small request (< 256 bytes minus per-chunk overhead): 45726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1. If one exists, use a remainderless chunk in associated smallbin. 45736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (Remainderless means that there are too few excess bytes to 45746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao represent as a chunk.) 45756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2. If it is big enough, use the dv chunk, which is normally the 45766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunk adjacent to the one used for the most recent small request. 45776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3. If one exists, split the smallest available chunk in a bin, 45786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao saving remainder in dv. 45796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4. If it is big enough, use the top chunk. 45806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5. If available, get memory from system and use it 45816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Otherwise, for a large request: 45826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 1. Find the smallest available binned chunk that fits, and use it 45836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if it is better fitting than dv chunk, splitting if necessary. 45846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 2. If better fitting than any binned chunk, use the dv chunk. 45856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 3. If it is big enough, use the top chunk. 45866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 4. If request size >= mmap threshold, try to directly mmap this chunk. 45876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 5. If available, get memory from system and use it 45886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The ugly goto's here ensure that postaction occurs along all paths. 45906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 45916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if USE_LOCKS 45936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); /* initialize in sys_alloc if not using locks */ 45946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 45956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 45966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(gm)) { 45976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem; 45986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb; 45996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes <= MAX_SMALL_REQUEST) { 46006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t idx; 46016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t smallbits; 46026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); 46036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao idx = small_index(nb); 46046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao smallbits = gm->smallmap >> idx; 46056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ 46076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr b, p; 46086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao idx += ~smallbits & 1; /* Uses next bin if idx empty */ 46096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao b = smallbin_at(gm, idx); 46106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = b->fd; 46116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(p) == small_index2size(idx)); 46126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_first_small_chunk(gm, b, p, idx); 46136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(gm, p, small_index2size(idx)); 46146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 46156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (nb > gm->dvsize) { 46206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ 46216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr b, p, r; 46226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize; 46236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 46246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); 46256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leastbit = least_bit(leftbits); 46266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_bit2idx(leastbit, i); 46276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao b = smallbin_at(gm, i); 46286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = b->fd; 46296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(p) == small_index2size(i)); 46306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_first_small_chunk(gm, b, p, i); 46316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rsize = small_index2size(i) - nb; 46326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Fit here cannot be remainderless if 4byte sizes */ 46336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) 46346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(gm, p, small_index2size(i)); 46356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 46366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 46376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao r = chunk_plus_offset(p, nb); 46386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 46396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao replace_dv(gm, r, rsize); 46406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 46426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { 46476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes >= MAX_REQUEST) 46536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ 46546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 46556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = pad_request(bytes); 46566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { 46576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (nb <= gm->dvsize) { 46636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = gm->dvsize - nb; 46646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = gm->dv; 46656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ 46666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = gm->dv = chunk_plus_offset(p, nb); 46676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gm->dvsize = rsize; 46686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 46696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 46706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* exhaust dv */ 46726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dvs = gm->dvsize; 46736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gm->dvsize = 0; 46746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao gm->dv = 0; 46756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(gm, p, dvs); 46766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 46786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (nb < gm->topsize) { /* Split top */ 46836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = gm->topsize -= nb; 46846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = gm->top; 46856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = gm->top = chunk_plus_offset(p, nb); 46866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao r->head = rsize | PINUSE_BIT; 46876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 46886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 46896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(gm, gm->top); 46906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(gm, mem, nb); 46916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 46926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 46936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = sys_alloc(gm, nb); 46956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 46966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao postaction: 46976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(gm); 46986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 46996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 47026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 47036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ---------------------------- free --------------------------- */ 47056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid dlfree(void* mem) { 47076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* 47086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Consolidate freed chunks with preceeding or succeeding bordering 47096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free chunks, if they exist, and then place in a bin. Intermixed 47106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with special cases for top, dv, mmapped chunks, and usage errors. 47116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 47126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 47146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 47156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if FOOTERS 47166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate fm = get_mstate_for(p); 47176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(fm)) { 47186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(fm, p); 47196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 47206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 47226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#define fm gm 47236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 47246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(fm)) { 47256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(fm, p); 47266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { 47276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = chunksize(p); 47286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = chunk_plus_offset(p, psize); 47296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!pinuse(p)) { 47306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t prevsize = p->prev_foot; 47316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) { 47326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize + MMAP_FOOT_PAD; 47336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) 47346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->footprint -= psize; 47356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 47366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 47386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr prev = chunk_minus_offset(p, prevsize); 47396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize; 47406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = prev; 47416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ 47426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p != fm->dv) { 47436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(fm, p, prevsize); 47446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if ((next->head & INUSE_BITS) == INUSE_BITS) { 47466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = psize; 47476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 47486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 47496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 47526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto erroraction; 47536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { 47576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!cinuse(next)) { /* consolidate forward */ 47586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (next == fm->top) { 47596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = fm->topsize += psize; 47606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->top = p; 47616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = tsize | PINUSE_BIT; 47626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == fm->dv) { 47636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dv = 0; 47646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = 0; 47656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (should_trim(fm, tsize)) 47676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sys_trim(fm, 0); 47686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 47696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (next == fm->dv) { 47716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dsize = fm->dvsize += psize; 47726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dv = p; 47736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, dsize); 47746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 47756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 47776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nsize = chunksize(next); 47786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += nsize; 47796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(fm, next, nsize); 47806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, psize); 47816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == fm->dv) { 47826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = psize; 47836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 47846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 47886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 47896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 47906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(psize)) { 47916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_small_chunk(fm, p, psize); 47926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_free_chunk(fm, p); 47936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 47946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 47956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr tp = (tchunkptr)p; 47966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_large_chunk(fm, tp, psize); 47976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_free_chunk(fm, p); 47986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (--fm->release_checks == 0) 47996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao release_unused_segments(fm); 48006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 48026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao erroraction: 48056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(fm, p); 48066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao postaction: 48076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(fm); 48086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !FOOTERS 48116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#undef fm 48126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 48136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 48146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 48156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlcalloc(size_t n_elements, size_t elem_size) { 48166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem; 48176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t req = 0; 48186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (n_elements != 0) { 48196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao req = n_elements * elem_size; 48206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (((n_elements | elem_size) & ~(size_t)0xffff) && 48216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (req / n_elements != elem_size)) 48226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao req = MAX_SIZE_T; /* force downstream failure on overflow */ 48236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = dlmalloc(req); 48256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 48266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 48276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (calloc_must_clear(p)) { 48286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Make sure to clear all of the buffer, not just the requested size. */ 48296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memset(mem, 0, chunksize(p) - overhead_for(p)); 48306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 48336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 48346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 48356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !ONLY_MSPACES */ 48366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 48376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------ Internal support for realloc, memalign, etc -------------- */ 48386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 48396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Try to realloc; only in-place unless can_move true */ 48406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, 48416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int can_move) { 48426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = 0; 48436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t oldsize = chunksize(p); 48446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = chunk_plus_offset(p, oldsize); 48456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, p) && ok_inuse(p) && 48466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ok_next(p, next) && ok_pinuse(next))) { 48476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) { 48486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp = mmap_resize(m, p, nb, can_move); 48496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (oldsize >= nb) { /* already big enough */ 48516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = oldsize - nb; 48526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ 48536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = chunk_plus_offset(p, nb); 48546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, nb); 48556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, r, rsize); 48566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dispose_chunk(m, r, rsize); 48576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp = p; 48596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (next == m->top) { /* extend into top */ 48616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldsize + m->topsize > nb) { 48626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = oldsize + m->topsize; 48636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newtopsize = newsize - nb; 48646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newtop = chunk_plus_offset(p, nb); 48656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, nb); 48666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newtop->head = newtopsize |PINUSE_BIT; 48676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->top = newtop; 48686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->topsize = newtopsize; 48696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp = p; 48706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (next == m->dv) { /* extend into dv */ 48736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dvs = m->dvsize; 48746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldsize + dvs >= nb) { 48756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dsize = oldsize + dvs - nb; 48766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (dsize >= MIN_CHUNK_SIZE) { 48776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = chunk_plus_offset(p, nb); 48786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr n = chunk_plus_offset(r, dsize); 48796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, nb); 48806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, dsize); 48816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao clear_pinuse(n); 48826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = dsize; 48836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = r; 48846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* exhaust dv */ 48866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = oldsize + dvs; 48876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, newsize); 48886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dvsize = 0; 48896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->dv = 0; 48906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp = p; 48926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 48946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (!cinuse(next)) { /* extend into next free chunk */ 48956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nextsize = chunksize(next); 48966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldsize + nextsize >= nb) { 48976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = oldsize + nextsize - nb; 48986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(m, next, nextsize); 48996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize < MIN_CHUNK_SIZE) { 49006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = oldsize + nextsize; 49016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, newsize); 49026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 49046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = chunk_plus_offset(p, nb); 49056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, nb); 49066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, r, rsize); 49076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dispose_chunk(m, r, rsize); 49086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp = p; 49106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 49146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(m, chunk2mem(p)); 49156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return newp; 49176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 49186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 49196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void* internal_memalign(mstate m, size_t alignment, size_t bytes) { 49206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 49216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ 49226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignment = MIN_CHUNK_SIZE; 49236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ 49246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t a = MALLOC_ALIGNMENT << 1; 49256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (a < alignment) a <<= 1; 49266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignment = a; 49276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes >= MAX_REQUEST - alignment) { 49296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (m != 0) { /* Test isn't needed but avoids compiler warning */ 49306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 49316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 49346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb = request2size(bytes); 49356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; 49366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = internal_malloc(m, req); 49376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 49386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 49396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (PREACTION(m)) 49406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 49416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ 49426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* 49436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Find an aligned spot inside chunk. Since we need to give 49446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao back leading space in a chunk of at least MIN_CHUNK_SIZE, if 49456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the first calculation places us at a spot with less than 49466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MIN_CHUNK_SIZE leader, we can move to the next aligned spot. 49476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao We've allocated enough total room so that this is always 49486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao possible. 49496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 49506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment - 49516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao SIZE_T_ONE)) & 49526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao -alignment)); 49536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? 49546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao br : br+alignment; 49556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = (mchunkptr)pos; 49566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t leadsize = pos - (char*)(p); 49576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = chunksize(p) - leadsize; 49586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 49596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ 49606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp->prev_foot = p->prev_foot + leadsize; 49616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao newp->head = newsize; 49626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* Otherwise, give back leader, use the rest */ 49646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, newp, newsize); 49656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, leadsize); 49666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dispose_chunk(m, p, leadsize); 49676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = newp; 49696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 49716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Give back spare room at the end */ 49726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!is_mmapped(p)) { 49736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size = chunksize(p); 49746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (size > nb + MIN_CHUNK_SIZE) { 49756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t remainder_size = size - nb; 49766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr remainder = chunk_plus_offset(p, nb); 49776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, nb); 49786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, remainder, remainder_size); 49796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dispose_chunk(m, remainder, remainder_size); 49806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 49836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 49846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert (chunksize(p) >= nb); 49856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(((size_t)mem & (alignment - 1)) == 0); 49866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, p); 49876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 49886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 49906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 49916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 49926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 49936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 49946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Common support for independent_X routines, handling 49956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao all of the combinations that can result. 49966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao The opts arg has: 49976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bit 0 set if all elements are same size (using sizes[0]) 49986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bit 1 set if elements should be zeroed 49996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 50006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void** ialloc(mstate m, 50016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t n_elements, 50026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t* sizes, 50036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int opts, 50046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* chunks[]) { 50056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t element_size; /* chunksize of each element, if all same */ 50076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t contents_size; /* total size of elements */ 50086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t array_size; /* request size of pointer array */ 50096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem; /* malloced aggregate space */ 50106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p; /* corresponding chunk */ 50116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t remainder_size; /* remaining bytes while splitting */ 50126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void** marray; /* either "chunks" or malloced ptr array */ 50136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr array_chunk; /* chunk for malloced ptr array */ 50146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t was_enabled; /* to disable mmap */ 50156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size; 50166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t i; 50176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 50196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* compute array length, if needed */ 50206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (chunks != 0) { 50216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (n_elements == 0) 50226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunks; /* nothing to do */ 50236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao marray = chunks; 50246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao array_size = 0; 50256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 50276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* if empty req, must still return chunk representing empty array */ 50286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (n_elements == 0) 50296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (void**)internal_malloc(m, 0); 50306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao marray = 0; 50316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao array_size = request2size(n_elements * (sizeof(void*))); 50326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* compute total element size */ 50356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (opts & 0x1) { /* all-same-size */ 50366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao element_size = request2size(*sizes); 50376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao contents_size = n_elements * element_size; 50386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* add up all the sizes */ 50406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao element_size = 0; 50416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao contents_size = 0; 50426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i != n_elements; ++i) 50436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao contents_size += request2size(sizes[i]); 50446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size = contents_size + array_size; 50476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* 50496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Allocate the aggregate chunk. First disable direct-mmapping so 50506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao malloc won't use it, since we would not be able to later 50516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao free/realloc space internal to a segregated mmap region. 50526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao */ 50536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao was_enabled = use_mmap(m); 50546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable_mmap(m); 50556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = internal_malloc(m, size - CHUNK_OVERHEAD); 50566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (was_enabled) 50576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao enable_mmap(m); 50586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem == 0) 50596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 50606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (PREACTION(m)) return 0; 50626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = mem2chunk(mem); 50636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao remainder_size = chunksize(p); 50646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(!is_mmapped(p)); 50666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (opts & 0x2) { /* optionally clear the elements */ 50686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); 50696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* If not provided, allocate the pointer array as final part of chunk */ 50726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (marray == 0) { 50736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t array_chunk_size; 50746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao array_chunk = chunk_plus_offset(p, contents_size); 50756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao array_chunk_size = remainder_size - contents_size; 50766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao marray = (void**) (chunk2mem(array_chunk)); 50776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); 50786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao remainder_size = contents_size; 50796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* split out elements */ 50826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; ; ++i) { 50836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao marray[i] = chunk2mem(p); 50846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (i != n_elements-1) { 50856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (element_size != 0) 50866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size = element_size; 50876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 50886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size = request2size(sizes[i]); 50896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao remainder_size -= size; 50906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, p, size); 50916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = chunk_plus_offset(p, size); 50926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* the final element absorbs any overallocation slop */ 50946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); 50956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 50966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 50986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 50996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if DEBUG 51006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (marray != chunks) { 51016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* final element must have exactly exhausted chunk */ 51026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (element_size != 0) { 51036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(remainder_size == element_size); 51046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 51066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(remainder_size == request2size(sizes[i])); 51076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, mem2chunk(marray)); 51096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (i = 0; i != n_elements; ++i) 51116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, mem2chunk(marray[i])); 51126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 51136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* DEBUG */ 51146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 51156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 51166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return marray; 51176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 51186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 51196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Try to free all pointers in the given array. 51206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Note: this could be made faster, by delaying consolidation, 51216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao at the price of disabling some user integrity checks, We 51226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao still optimize some consolidations by combining adjacent 51236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao chunks before freeing, which will occur often if allocated 51246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with ialloc or the array is sorted. 51256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 51266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic size_t internal_bulk_free(mstate m, void* array[], size_t nelem) { 51276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t unfreed = 0; 51286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 51296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void** a; 51306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void** fence = &(array[nelem]); 51316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (a = array; a != fence; ++a) { 51326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = *a; 51336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 51346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 51356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = chunksize(p); 51366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if FOOTERS 51376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (get_mstate_for(p) != m) { 51386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ++unfreed; 51396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao continue; 51406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif 51426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, p); 51436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *a = 0; 51446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(m, p) && ok_inuse(p))) { 51456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void ** b = a + 1; /* try to merge with next chunk */ 51466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = next_chunk(p); 51476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (b != fence && *b == chunk2mem(next)) { 51486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t newsize = chunksize(next) + psize; 51496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse(m, p, newsize); 51506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *b = chunk2mem(p); 51516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 51536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dispose_chunk(m, p, psize); 51546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 51566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CORRUPTION_ERROR_ACTION(m); 51576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 51586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (should_trim(m, m->topsize)) 51626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sys_trim(m, 0); 51636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 51646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return unfreed; 51666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 51676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 51686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* Traversal */ 51696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MALLOC_INSPECT_ALL 51706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic void internal_inspect_all(mstate m, 51716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void(*handler)(void *start, 51726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *end, 51736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used_bytes, 51746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* callback_arg), 51756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* arg) { 51766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_initialized(m)) { 51776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr top = m->top; 51786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr s; 51796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (s = &m->seg; s != 0; s = s->next) { 51806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr q = align_as_chunk(s->base); 51816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { 51826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = next_chunk(q); 51836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = chunksize(q); 51846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used; 51856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* start; 51866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_inuse(q)) { 51876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ 51886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao start = chunk2mem(q); 51896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 51916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao used = 0; 51926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(sz)) { /* offset by possible bookkeeping */ 51936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao start = (void*)((char*)q + sizeof(struct malloc_chunk)); 51946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 51966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao start = (void*)((char*)q + sizeof(struct malloc_tree_chunk)); 51976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 51996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (start < (void*)next) /* skip if all space is bookkeeping */ 52006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao handler(start, next, used, arg); 52016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (q == top) 52026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao break; 52036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao q = next; 52046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 52086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_INSPECT_ALL */ 52096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ------------------ Exported realloc, memalign, etc -------------------- */ 52116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !ONLY_MSPACES 52136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlrealloc(void* oldmem, size_t bytes) { 52156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 52166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldmem == 0) { 52176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = dlmalloc(bytes); 52186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes >= MAX_REQUEST) { 52206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 52216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef REALLOC_ZERO_BYTES_FREES 52236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes == 0) { 52246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao dlfree(oldmem); 52256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* REALLOC_ZERO_BYTES_FREES */ 52276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 52286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb = request2size(bytes); 52296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr oldp = mem2chunk(oldmem); 52306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ! FOOTERS 52316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = gm; 52326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 52336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = get_mstate_for(oldp); 52346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(m)) { 52356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(m, oldmem); 52366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 52376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 52396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 52406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); 52416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 52426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (newp != 0) { 52436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, newp); 52446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(newp); 52456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 52476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = internal_malloc(m, bytes); 52486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 52496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t oc = chunksize(oldp) - overhead_for(oldp); 52506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memcpy(mem, oldmem, (oc < bytes)? oc : bytes); 52516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao internal_free(m, oldmem); 52526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 52576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 52586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlrealloc_in_place(void* oldmem, size_t bytes) { 52606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 52616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldmem != 0) { 52626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes >= MAX_REQUEST) { 52636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 52646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 52666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb = request2size(bytes); 52676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr oldp = mem2chunk(oldmem); 52686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ! FOOTERS 52696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = gm; 52706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 52716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = get_mstate_for(oldp); 52726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(m)) { 52736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(m, oldmem); 52746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 52756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 52776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 52786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); 52796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 52806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (newp == oldp) { 52816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, newp); 52826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = oldmem; 52836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 52886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 52896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlmemalign(size_t alignment, size_t bytes) { 52916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (alignment <= MALLOC_ALIGNMENT) { 52926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return dlmalloc(bytes); 52936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 52946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_memalign(gm, alignment, bytes); 52956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 52966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 52976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint dlposix_memalign(void** pp, size_t alignment, size_t bytes) { 52986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 52996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (alignment == MALLOC_ALIGNMENT) 53006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = dlmalloc(bytes); 53016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 53026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t d = alignment / sizeof(void*); 53036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t r = alignment % sizeof(void*); 53046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0) 53056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return EINVAL; 53066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes <= MAX_REQUEST - alignment) { 53076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (alignment < MIN_CHUNK_SIZE) 53086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao alignment = MIN_CHUNK_SIZE; 53096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = internal_memalign(gm, alignment, bytes); 53106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem == 0) 53136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ENOMEM; 53146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 53156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *pp = mem; 53166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 53176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlvalloc(size_t bytes) { 53216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t pagesz; 53226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 53236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pagesz = mparams.page_size; 53246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return dlmemalign(pagesz, bytes); 53256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* BEGIN android-changed: added overflow check */ 53286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* dlpvalloc(size_t bytes) { 53296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t pagesz; 53306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size; 53316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 53326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao pagesz = mparams.page_size; 53336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size = (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE); 53346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (size < bytes) { 53356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return NULL; 53366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return dlmemalign(pagesz, size); 53386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* END android-change */ 53406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid** dlindependent_calloc(size_t n_elements, size_t elem_size, 53426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* chunks[]) { 53436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = elem_size; /* serves as 1-element array */ 53446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ialloc(gm, n_elements, &sz, 3, chunks); 53456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid** dlindependent_comalloc(size_t n_elements, size_t sizes[], 53486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* chunks[]) { 53496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ialloc(gm, n_elements, sizes, 0, chunks); 53506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlbulk_free(void* array[], size_t nelem) { 53536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_bulk_free(gm, array, nelem); 53546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MALLOC_INSPECT_ALL 53576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid dlmalloc_inspect_all(void(*handler)(void *start, 53586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *end, 53596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used_bytes, 53606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* callback_arg), 53616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* arg) { 53626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 53636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(gm)) { 53646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao internal_inspect_all(gm, handler, arg); 53656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(gm); 53666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_INSPECT_ALL */ 53696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint dlmalloc_trim(size_t pad) { 53716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int result = 0; 53726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 53736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(gm)) { 53746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = sys_trim(gm, pad); 53756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(gm); 53766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 53776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 53786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_footprint(void) { 53816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return gm->footprint; 53826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_max_footprint(void) { 53856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return gm->max_footprint; 53866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_footprint_limit(void) { 53896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t maf = gm->footprint_limit; 53906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return maf == 0 ? MAX_SIZE_T : maf; 53916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 53926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 53936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_set_footprint_limit(size_t bytes) { 53946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t result; /* invert sense of 0 */ 53956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes == 0) 53966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = granularity_align(1); /* Use minimal size */ 53976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes == MAX_SIZE_T) 53986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = 0; /* disable */ 53996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 54006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = granularity_align(bytes); 54016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return gm->footprint_limit = result; 54026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 54056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct mallinfo dlmallinfo(void) { 54066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_mallinfo(gm); 54076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 54096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLOC_STATS 54116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid dlmalloc_stats() { 54126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao internal_malloc_stats(gm); 54136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLOC_STATS */ 54156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint dlmallopt(int param_number, int value) { 54176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return change_mparam(param_number, value); 54186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* BEGIN android-changed: added const */ 54216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t dlmalloc_usable_size(const void* mem) { 54226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* END android-change */ 54236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 54246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 54256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_inuse(p)) 54266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunksize(p) - overhead_for(p); 54276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 54286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 54296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* !ONLY_MSPACES */ 54326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------------- user mspaces ---------------------------- */ 54346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MSPACES 54366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostatic mstate init_user_mstate(char* tbase, size_t tsize) { 54386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t msize = pad_request(sizeof(struct malloc_state)); 54396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr mn; 54406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr msp = align_as_chunk(tbase); 54416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = (mstate)(chunk2mem(msp)); 54426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memset(m, 0, msize); 54436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)INITIAL_LOCK(&m->mutex); 54446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msp->head = (msize|INUSE_BITS); 54456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.base = m->least_addr = tbase; 54466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.size = m->footprint = m->max_footprint = tsize; 54476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->magic = mparams.magic; 54486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->release_checks = MAX_RELEASE_CHECK_RATE; 54496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->mflags = mparams.default_mflags; 54506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->extp = 0; 54516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->exts = 0; 54526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable_contiguous(m); 54536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_bins(m); 54546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mn = next_chunk(mem2chunk(m)); 54556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); 54566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(m, m->top); 54576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return m; 54586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaomspace create_mspace(size_t capacity, int locked) { 54616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = 0; 54626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t msize; 54636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 54646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msize = pad_request(sizeof(struct malloc_state)); 54656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { 54666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rs = ((capacity == 0)? mparams.granularity : 54676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (capacity + TOP_FOOT_SIZE + msize)); 54686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = granularity_align(rs); 54696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* tbase = (char*)(CALL_MMAP(tsize)); 54706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (tbase != CMFAIL) { 54716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m = init_user_mstate(tbase, tsize); 54726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.sflags = USE_MMAP_BIT; 54736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_lock(m, locked); 54746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 54756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 54766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (mspace)m; 54776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaomspace create_mspace_with_base(void* base, size_t capacity, int locked) { 54806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = 0; 54816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t msize; 54826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ensure_initialization(); 54836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msize = pad_request(sizeof(struct malloc_state)); 54846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (capacity > msize + TOP_FOOT_SIZE && 54856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { 54866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m = init_user_mstate((char*)base, capacity); 54876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao m->seg.sflags = EXTERN_BIT; 54886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_lock(m, locked); 54896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 54906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (mspace)m; 54916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 54926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 54936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint mspace_track_large_chunks(mspace msp, int enable) { 54946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int ret = 0; 54956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 54966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(ms)) { 54976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!use_mmap(ms)) { 54986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ret = 1; 54996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!enable) { 55016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao enable_mmap(ms); 55026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } else { 55036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao disable_mmap(ms); 55046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(ms); 55066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ret; 55086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 55096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t destroy_mspace(mspace msp) { 55116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t freed = 0; 55126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 55136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 55146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao msegmentptr sp = &ms->seg; 55156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */ 55166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao while (sp != 0) { 55176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao char* base = sp->base; 55186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t size = sp->size; 55196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao flag_t flag = sp->sflags; 55206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)base; /* placate people compiling -Wunused-variable */ 55216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sp = sp->next; 55226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && 55236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao CALL_MUNMAP(base, size) == 0) 55246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao freed += size; 55256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 55286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 55296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return freed; 55316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 55326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 55346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace versions of routines are near-clones of the global 55356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao versions. This is not so nice but better than the alternatives. 55366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 55376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* mspace_malloc(mspace msp, size_t bytes) { 55396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 55406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 55416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 55426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 55436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(ms)) { 55456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem; 55466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb; 55476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes <= MAX_SMALL_REQUEST) { 55486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t idx; 55496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t smallbits; 55506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); 55516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao idx = small_index(nb); 55526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao smallbits = ms->smallmap >> idx; 55536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ 55556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr b, p; 55566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao idx += ~smallbits & 1; /* Uses next bin if idx empty */ 55576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao b = smallbin_at(ms, idx); 55586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = b->fd; 55596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(p) == small_index2size(idx)); 55606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_first_small_chunk(ms, b, p, idx); 55616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(ms, p, small_index2size(idx)); 55626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 55636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 55646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 55656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (nb > ms->dvsize) { 55686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ 55696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr b, p, r; 55706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize; 55716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao bindex_t i; 55726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); 55736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao binmap_t leastbit = least_bit(leftbits); 55746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao compute_bit2idx(leastbit, i); 55756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao b = smallbin_at(ms, i); 55766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = b->fd; 55776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao assert(chunksize(p) == small_index2size(i)); 55786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_first_small_chunk(ms, b, p, i); 55796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao rsize = small_index2size(i) - nb; 55806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao /* Fit here cannot be remainderless if 4byte sizes */ 55816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) 55826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(ms, p, small_index2size(i)); 55836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 55846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 55856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao r = chunk_plus_offset(p, nb); 55866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 55876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao replace_dv(ms, r, rsize); 55886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 55906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 55916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 55926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 55946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { 55956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 55966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 55976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 55996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes >= MAX_REQUEST) 56016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ 56026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 56036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nb = pad_request(bytes); 56046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { 56056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 56066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 56076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (nb <= ms->dvsize) { 56116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = ms->dvsize - nb; 56126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = ms->dv; 56136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ 56146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = ms->dv = chunk_plus_offset(p, nb); 56156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ms->dvsize = rsize; 56166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(r, rsize); 56176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 56186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { /* exhaust dv */ 56206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dvs = ms->dvsize; 56216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ms->dvsize = 0; 56226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ms->dv = 0; 56236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_inuse_and_pinuse(ms, p, dvs); 56246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 56266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 56276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 56286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (nb < ms->topsize) { /* Split top */ 56316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t rsize = ms->topsize -= nb; 56326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = ms->top; 56336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr r = ms->top = chunk_plus_offset(p, nb); 56346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao r->head = rsize | PINUSE_BIT; 56356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 56366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(p); 56376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_top_chunk(ms, ms->top); 56386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_malloced_chunk(ms, mem, nb); 56396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 56406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = sys_alloc(ms, nb); 56436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao postaction: 56456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(ms); 56466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 56476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 56506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 56516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid mspace_free(mspace msp, void* mem) { 56536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 56546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 56556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if FOOTERS 56566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate fm = get_mstate_for(p); 56576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)msp; /* placate people compiling -Wunused */ 56586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 56596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate fm = (mstate)msp; 56606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 56616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(fm)) { 56626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(fm, p); 56636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return; 56646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(fm)) { 56666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(fm, p); 56676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { 56686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t psize = chunksize(p); 56696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr next = chunk_plus_offset(p, psize); 56706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!pinuse(p)) { 56716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t prevsize = p->prev_foot; 56726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_mmapped(p)) { 56736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize + MMAP_FOOT_PAD; 56746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) 56756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->footprint -= psize; 56766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 56776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 56796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr prev = chunk_minus_offset(p, prevsize); 56806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += prevsize; 56816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p = prev; 56826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ 56836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p != fm->dv) { 56846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(fm, p, prevsize); 56856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if ((next->head & INUSE_BITS) == INUSE_BITS) { 56876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = psize; 56886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 56896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 56906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 56936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto erroraction; 56946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 56966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 56976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { 56986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!cinuse(next)) { /* consolidate forward */ 56996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (next == fm->top) { 57006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t tsize = fm->topsize += psize; 57016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->top = p; 57026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao p->head = tsize | PINUSE_BIT; 57036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == fm->dv) { 57046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dv = 0; 57056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = 0; 57066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (should_trim(fm, tsize)) 57086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sys_trim(fm, 0); 57096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 57106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (next == fm->dv) { 57126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t dsize = fm->dvsize += psize; 57136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dv = p; 57146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, dsize); 57156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 57166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 57186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nsize = chunksize(next); 57196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao psize += nsize; 57206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao unlink_chunk(fm, next, nsize); 57216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_size_and_pinuse_of_free_chunk(p, psize); 57226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (p == fm->dv) { 57236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao fm->dvsize = psize; 57246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 57256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 57296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao set_free_with_pinuse(p, psize, next); 57306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 57316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_small(psize)) { 57326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_small_chunk(fm, p, psize); 57336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_free_chunk(fm, p); 57346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 57366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao tchunkptr tp = (tchunkptr)p; 57376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao insert_large_chunk(fm, tp, psize); 57386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_free_chunk(fm, p); 57396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (--fm->release_checks == 0) 57406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao release_unused_segments(fm); 57416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao goto postaction; 57436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao erroraction: 57466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(fm, p); 57476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao postaction: 57486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(fm); 57496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 57526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 57536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { 57546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem; 57556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t req = 0; 57566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 57576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 57586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 57596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 57606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (n_elements != 0) { 57626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao req = n_elements * elem_size; 57636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (((n_elements | elem_size) & ~(size_t)0xffff) && 57646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (req / n_elements != elem_size)) 57656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao req = MAX_SIZE_T; /* force downstream failure on overflow */ 57666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = internal_malloc(ms, req); 57686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0 && calloc_must_clear(mem2chunk(mem))) 57696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memset(mem, 0, req); 57706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 57716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 57726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 57736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { 57746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 57756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldmem == 0) { 57766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = mspace_malloc(msp, bytes); 57776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes >= MAX_REQUEST) { 57796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 57806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#ifdef REALLOC_ZERO_BYTES_FREES 57826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (bytes == 0) { 57836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_free(msp, oldmem); 57846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* REALLOC_ZERO_BYTES_FREES */ 57866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 57876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb = request2size(bytes); 57886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr oldp = mem2chunk(oldmem); 57896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ! FOOTERS 57906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = (mstate)msp; 57916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 57926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = get_mstate_for(oldp); 57936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(m)) { 57946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(m, oldmem); 57956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 57966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 57976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 57986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 57996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); 58006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 58016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (newp != 0) { 58026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, newp); 58036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = chunk2mem(newp); 58046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 58066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = mspace_malloc(m, bytes); 58076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 58086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t oc = chunksize(oldp) - overhead_for(oldp); 58096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memcpy(mem, oldmem, (oc < bytes)? oc : bytes); 58106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mspace_free(m, oldmem); 58116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 58166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { 58196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* mem = 0; 58206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (oldmem != 0) { 58216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes >= MAX_REQUEST) { 58226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MALLOC_FAILURE_ACTION; 58236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 58256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t nb = request2size(bytes); 58266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr oldp = mem2chunk(oldmem); 58276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if ! FOOTERS 58286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = (mstate)msp; 58296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#else /* FOOTERS */ 58306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate m = get_mstate_for(oldp); 58316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (void)msp; /* placate people compiling -Wunused */ 58326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(m)) { 58336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(m, oldmem); 58346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 58356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* FOOTERS */ 58376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(m)) { 58386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); 58396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(m); 58406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (newp == oldp) { 58416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao check_inuse_chunk(m, newp); 58426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mem = oldmem; 58436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mem; 58486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { 58516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 58526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 58536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 58546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 58556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (alignment <= MALLOC_ALIGNMENT) 58576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return mspace_malloc(msp, bytes); 58586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_memalign(ms, alignment, bytes); 58596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid** mspace_independent_calloc(mspace msp, size_t n_elements, 58626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t elem_size, void* chunks[]) { 58636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sz = elem_size; /* serves as 1-element array */ 58646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 58656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 58666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 58676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 58686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ialloc(ms, n_elements, &sz, 3, chunks); 58706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid** mspace_independent_comalloc(mspace msp, size_t n_elements, 58736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t sizes[], void* chunks[]) { 58746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 58756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 58766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 58776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 58786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ialloc(ms, n_elements, sizes, 0, chunks); 58806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) { 58836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_bulk_free((mstate)msp, array, nelem); 58846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 58856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 58866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if MALLOC_INSPECT_ALL 58876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid mspace_inspect_all(mspace msp, 58886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void(*handler)(void *start, 58896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *end, 58906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t used_bytes, 58916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* callback_arg), 58926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void* arg) { 58936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 58946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 58956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(ms)) { 58966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao internal_inspect_all(ms, handler, arg); 58976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(ms); 58986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 58996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MALLOC_INSPECT_ALL */ 59056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint mspace_trim(mspace msp, size_t pad) { 59076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao int result = 0; 59086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!PREACTION(ms)) { 59116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = sys_trim(ms, pad); 59126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao POSTACTION(ms); 59136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 59196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLOC_STATS 59226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaovoid mspace_malloc_stats(mspace msp) { 59236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao internal_malloc_stats(ms); 59266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLOC_STATS */ 59326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_footprint(mspace msp) { 59346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t result = 0; 59356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = ms->footprint; 59386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 59436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_max_footprint(mspace msp) { 59466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t result = 0; 59476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = ms->max_footprint; 59506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 59556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_footprint_limit(mspace msp) { 59586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t result = 0; 59596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t maf = ms->footprint_limit; 59626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = (maf == 0) ? MAX_SIZE_T : maf; 59636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 59686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_set_footprint_limit(mspace msp, size_t bytes) { 59716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size_t result = 0; 59726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ok_magic(ms)) { 59746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes == 0) 59756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = granularity_align(1); /* Use minimal size */ 59766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (bytes == MAX_SIZE_T) 59776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = 0; /* disable */ 59786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 59796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao result = granularity_align(bytes); 59806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ms->footprint_limit = result; 59816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else { 59836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return result; 59866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#if !NO_MALLINFO 59896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaostruct mallinfo mspace_mallinfo(mspace msp) { 59906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mstate ms = (mstate)msp; 59916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (!ok_magic(ms)) { 59926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao USAGE_ERROR_ACTION(ms,ms); 59936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 59946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return internal_mallinfo(ms); 59956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 59966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* NO_MALLINFO */ 59976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 59986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaosize_t mspace_usable_size(const void* mem) { 59996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (mem != 0) { 60006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao mchunkptr p = mem2chunk(mem); 60016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (is_inuse(p)) 60026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return chunksize(p) - overhead_for(p); 60036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return 0; 60056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 60066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gaoint mspace_mallopt(int param_number, int value) { 60086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return change_mparam(param_number, value); 60096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao} 60106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao#endif /* MSPACES */ 60126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* -------------------- Alternative MORECORE functions ------------------- */ 60156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* 60176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Guidelines for creating a custom version of MORECORE: 60186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * For best performance, MORECORE should allocate in multiples of pagesize. 60206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * MORECORE may allocate more memory than requested. (Or even less, 60216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao but this will usually result in a malloc failure.) 60226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * MORECORE must not allocate memory when given argument zero, but 60236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao instead return one past the end address of memory from previous 60246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao nonzero call. 60256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * For best performance, consecutive calls to MORECORE with positive 60266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao arguments should return increasing addresses, indicating that 60276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao space has been contiguously extended. 60286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Even though consecutive calls to MORECORE need not return contiguous 60296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao addresses, it must be OK for malloc'ed chunks to span multiple 60306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao regions in those cases where they do happen to be contiguous. 60316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * MORECORE need not handle negative arguments -- it may instead 60326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao just return MFAIL when given negative arguments. 60336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Negative arguments are always multiples of pagesize. MORECORE 60346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao must not misinterpret negative args as large positive unsigned 60356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao args. You can suppress all such calls from even occurring by defining 60366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao MORECORE_CANNOT_TRIM, 60376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao As an example alternative MORECORE, here is a custom allocator 60396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao kindly contributed for pre-OSX macOS. It uses virtually but not 60406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao necessarily physically contiguous non-paged memory (locked in, 60416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao present and won't get swapped out). You can use it by uncommenting 60426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao this section, adding some #includes, and setting up the appropriate 60436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao defines above: 60446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define MORECORE osMoreCore 60466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao There is also a shutdown routine that should somehow be called for 60486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao cleanup upon program exit. 60496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define MAX_POOL_ENTRIES 100 60516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao #define MINIMUM_MORECORE_SIZE (64 * 1024U) 60526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static int next_os_pool; 60536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *our_os_pools[MAX_POOL_ENTRIES]; 60546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *osMoreCore(int size) 60566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void *ptr = 0; 60586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao static void *sbrk_top = 0; 60596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (size > 0) 60616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (size < MINIMUM_MORECORE_SIZE) 60636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao size = MINIMUM_MORECORE_SIZE; 60646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (CurrentExecutionLevel() == kTaskLevel) 60656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); 60666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (ptr == 0) 60676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (void *) MFAIL; 60696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // save ptrs so they can be freed during cleanup 60716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao our_os_pools[next_os_pool] = ptr; 60726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao next_os_pool++; 60736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); 60746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao sbrk_top = (char *) ptr + size; 60756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return ptr; 60766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else if (size < 0) 60786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // we don't currently support shrink behavior 60806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return (void *) MFAIL; 60816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao else 60836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao return sbrk_top; 60856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 60876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // cleanup any allocated memory pools 60896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao // called as last thing before shutting down driver 60906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void osCleanupMem(void) 60926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao void **ptr; 60946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 60956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) 60966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao if (*ptr) 60976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao { 60986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao PoolDeallocate(*ptr); 60996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao *ptr = 0; 61006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 61016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao } 61026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 61046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao/* ----------------------------------------------------------------------- 61076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh GaoHistory: 61086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea 61096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * fix bad comparison in dlposix_memalign 61106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * don't reuse adjusted asize in sys_alloc 61116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion 61126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * reduce compiler warnings -- thanks to all who reported/suggested these 61136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) 61156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Always perform unlink checks unless INSECURE 61166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add posix_memalign. 61176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Improve realloc to expand in more cases; expose realloc_in_place. 61186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks to Peter Buhr for the suggestion. 61196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add footprint_limit, inspect_all, bulk_free. Thanks 61206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to Barry Hayes and others for the suggestions. 61216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Internal refactorings to avoid calls while holding locks 61226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use non-reentrant locks by default. Thanks to Roland McGrath 61236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao for the suggestion. 61246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Small fixes to mspace_destroy, reset_on_error. 61256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Various configuration extensions/changes. Thanks 61266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to all who contributed these. 61276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu) 61296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Update Creative Commons URL 61306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) 61326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use zeros instead of prev foot for is_mmapped 61336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add mspace_track_large_chunks; thanks to Jean Brouwers 61346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix set_inuse in internal_realloc; thanks to Jean Brouwers 61356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix insufficient sys_alloc padding when using 16byte alignment 61366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix bad error check in mspace_footprint 61376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Adaptations for ptmalloc; thanks to Wolfram Gloger. 61386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Reentrant spin locks; thanks to Earl Chew and others 61396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Win32 improvements; thanks to Niall Douglas and Earl Chew 61406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options 61416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Extension hook in malloc_state 61426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Various small adjustments to reduce warnings on some compilers 61436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Various configuration extensions/changes for more platforms. Thanks 61446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao to all who contributed these. 61456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) 61476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add max_footprint functions 61486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Ensure all appropriate literals are size_t 61496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix conditional compilation problem for some #define settings 61506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Avoid concatenating segments with the one provided 61516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao in create_mspace_with_base 61526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Rename some variables to avoid compiler shadowing warnings 61536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use explicit lock initialization. 61546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Better handling of sbrk interference. 61556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Simplify and fix segment insertion, trimming and mspace_destroy 61566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x 61576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Thanks especially to Dennis Flanagan for help on these. 61586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) 61606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix memalign brace error. 61616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) 61636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix improper #endif nesting in C++ 61646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add explicit casts needed for C++ 61656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) 61676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use trees for large bins 61686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Support mspaces 61696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use segments to unify sbrk-based and mmap-based system allocation, 61706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao removing need for emulation on most platforms without sbrk. 61716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Default safety checks 61726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Optional footer checks. Thanks to William Robertson for the idea. 61736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Internal code refactoring 61746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Incorporate suggestions and platform-specific changes. 61756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, 61766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Aaron Bachmann, Emery Berger, and others. 61776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Speed up non-fastbin processing enough to remove fastbins. 61786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Remove useless cfree() to avoid conflicts with other apps. 61796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Remove internal memcpy, memset. Compilers handle builtins better. 61806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Remove some options that no one ever used and rename others. 61816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) 61836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix malloc_state bitmap array misdeclaration 61846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) 61866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Allow tuning of FIRST_SORTED_BIN_SIZE 61876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. 61886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Better detection and support for non-contiguousness of MORECORE. 61896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger 61906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Bypass most of malloc if no frees. Thanks To Emery Berger. 61916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix freeing of old top non-contiguous chunk im sysmalloc. 61926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Raised default trim and map thresholds to 256K. 61936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix mmap-related #defines. Thanks to Lubos Lunak. 61946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. 61956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Branch-free bin calculation 61966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Default trim and mmap thresholds now 256K. 61976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 61986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) 61996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Introduce independent_comalloc and independent_calloc. 62006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks to Michael Pachos for motivation and help. 62016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Make optional .h file available 62026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Allow > 2GB requests on 32bit systems. 62036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>. 62046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks also to Andreas Mueller <a.mueller at paradatec.de>, 62056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao and Anonymous. 62066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for 62076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao helping test this.) 62086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * memalign: check alignment arg 62096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * realloc: don't try to shift chunks backwards, since this 62106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao leads to more fragmentation in some programs and doesn't 62116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao seem to help in any others. 62126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Collect all cases in malloc requiring system memory into sysmalloc 62136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use mmap as backup to sbrk 62146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Place all internal state in malloc_state 62156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Introduce fastbins (although similar to 2.5.1) 62166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Many minor tunings and cosmetic improvements 62176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK 62186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS 62196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Thanks to Tony E. Bennett <tbennett@nvidia.com> and others. 62206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Include errno.h to support default failure action. 62216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) 62236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * return null for negative arguments 62246661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com> 62256661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' 62266661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (e.g. WIN32 platforms) 62276661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Cleanup header file inclusion for WIN32 platforms 62286661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Cleanup code to avoid Microsoft Visual C++ compiler complaints 62296661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing 62306661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao memory allocation routines 62316661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) 62326661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to 62336661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao usage of 'assert' in non-WIN32 code 62346661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to 62356661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao avoid infinite loop 62366661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Always call 'fREe()' rather than 'free()' 62376661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62386661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) 62396661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fixed ordering problem with boundary-stamping 62406661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62416661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) 62426661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added pvalloc, as recommended by H.J. Liu 62436661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added 64bit pointer support mainly from Wolfram Gloger 62446661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added anonymously donated WIN32 sbrk emulation 62456661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen 62466661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * malloc_extend_top: fix mask error that caused wastage after 62476661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao foreign sbrks 62486661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add linux mremap support code from HJ Liu 62496661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62506661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) 62516661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Integrated most documentation with the code. 62526661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add support for mmap, with help from 62536661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Wolfram Gloger (Gloger@lrz.uni-muenchen.de). 62546661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use last_remainder in more cases. 62556661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Pack bins using idea from colin@nyx10.cs.du.edu 62566661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use ordered bins instead of best-fit threshhold 62576661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Eliminate block-local decls to simplify tracing and debugging. 62586661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Support another case of realloc via move into top 62596661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Fix error occuring when initial sbrk_base not word-aligned. 62606661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Rely on page size for units instead of SBRK_UNIT to 62616661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao avoid surprises about sbrk alignment conventions. 62626661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add mallinfo, mallopt. Thanks to Raymond Nijssen 62636661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (raymond@es.ele.tue.nl) for the suggestion. 62646661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add `pad' argument to malloc_trim and top_pad mallopt parameter. 62656661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * More precautions for cases where other routines call sbrk, 62666661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). 62676661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added macros etc., allowing use in linux libc from 62686661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao H.J. Lu (hjl@gnu.ai.mit.edu) 62696661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Inverted this history list 62706661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62716661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) 62726661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Re-tuned and fixed to behave more nicely with V2.6.0 changes. 62736661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Removed all preallocation code since under current scheme 62746661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the work required to undo bad preallocations exceeds 62756661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao the work saved in good cases for most test programs. 62766661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * No longer use return list or unconsolidated bins since 62776661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao no scheme using them consistently outperforms those that don't 62786661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao given above changes. 62796661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use best fit for very large chunks to prevent some worst-cases. 62806661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added some support for debugging 62816661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62826661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) 62836661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Removed footers when chunks are in use. Thanks to 62846661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Paul Wilson (wilson@cs.texas.edu) for the suggestion. 62856661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62866661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) 62876661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Added malloc_trim, with help from Wolfram Gloger 62886661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (wmglo@Dent.MED.Uni-Muenchen.DE). 62896661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62906661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) 62916661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 62926661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) 62936661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * realloc: try to expand in both directions 62946661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * malloc: swap order of clean-bin strategy; 62956661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * realloc: only conditionally expand backwards 62966661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Try not to scavenge used bins 62976661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Use bin counts as a guide to preallocation 62986661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Occasionally bin return list chunks in first scan 62996661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add a few optimizations from colin@nyx10.cs.du.edu 63006661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 63016661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) 63026661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * faster bin computation & slightly different binning 63036661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * merged all consolidations to one part of malloc proper 63046661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao (eliminating old malloc_find_space & malloc_clean_bin) 63056661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Scan 2 returns chunks (not just 1) 63066661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Propagate failure in realloc if malloc returns 0 63076661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Add stuff to allow compilation on non-ANSI compilers 63086661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao from kpv@research.att.com 63096661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 63106661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) 63116661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * removed potential for odd address access in prev_chunk 63126661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * removed dependency on getpagesize.h 63136661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * misc cosmetics and a bit more internal documentation 63146661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * anticosmetics: mangled names in macros to evade debugger strangeness 63156661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * tested on sparc, hp-700, dec-mips, rs6000 63166661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao with gcc & native cc (hp, dec only) allowing 63176661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Detlefs & Zorn comparison study (in SIGPLAN Notices.) 63186661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 63196661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) 63206661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao * Based loosely on libg++-1.2X malloc. (It retains some of the overall 63216661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao structure of old version, but most details differ.) 63226661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao 63236661f3ca66b55d8f5a57b96fec97efaf8f3897a5Josh Gao*/ 6324