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