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