malloc.c.h

Go to the documentation of this file.
00001 /*
00002   This is a version (aka dlmalloc) of malloc/free/realloc written by
00003   Doug Lea and released to the public domain, as explained at
00004   http://creativecommons.org/licenses/publicdomain.  Send questions,
00005   comments, complaints, performance data, etc to dl@cs.oswego.edu
00006 
00007 * Version pre-2.8.4 Mon Nov 27 11:22:37 2006    (dl at gee)
00008 
00009    Note: There may be an updated version of this malloc obtainable at
00010            ftp://gee.cs.oswego.edu/pub/misc/malloc.c
00011          Check before installing!
00012 
00013 * Quickstart
00014 
00015   This library is all in one file to simplify the most common usage:
00016   ftp it, compile it (-O3), and link it into another program. All of
00017   the compile-time options default to reasonable values for use on
00018   most platforms.  You might later want to step through various
00019   compile-time and dynamic tuning options.
00020 
00021   For convenience, an include file for code using this malloc is at:
00022      ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.4.h
00023   You don't really need this .h file unless you call functions not
00024   defined in your system include files.  The .h file contains only the
00025   excerpts from this file needed for using this malloc on ANSI C/C++
00026   systems, so long as you haven't changed compile-time options about
00027   naming and tuning parameters.  If you do, then you can create your
00028   own malloc.h that does include all settings by cutting at the point
00029   indicated below. Note that you may already by default be using a C
00030   library containing a malloc that is based on some version of this
00031   malloc (for example in linux). You might still want to use the one
00032   in this file to customize settings or to avoid overheads associated
00033   with library versions.
00034 
00035 * Vital statistics:
00036 
00037   Supported pointer/size_t representation:       4 or 8 bytes
00038        size_t MUST be an unsigned type of the same width as
00039        pointers. (If you are using an ancient system that declares
00040        size_t as a signed type, or need it to be a different width
00041        than pointers, you can use a previous release of this malloc
00042        (e.g. 2.7.2) supporting these.)
00043 
00044   Alignment:                                     8 bytes (default)
00045        This suffices for nearly all current machines and C compilers.
00046        However, you can define MALLOC_ALIGNMENT to be wider than this
00047        if necessary (up to 128bytes), at the expense of using more space.
00048 
00049   Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
00050                                           8 or 16 bytes (if 8byte sizes)
00051        Each malloced chunk has a hidden word of overhead holding size
00052        and status information, and additional cross-check word
00053        if FOOTERS is defined.
00054 
00055   Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
00056                           8-byte ptrs:  32 bytes    (including overhead)
00057 
00058        Even a request for zero bytes (i.e., malloc(0)) returns a
00059        pointer to something of the minimum allocatable size.
00060        The maximum overhead wastage (i.e., number of extra bytes
00061        allocated than were requested in malloc) is less than or equal
00062        to the minimum size, except for requests >= mmap_threshold that
00063        are serviced via mmap(), where the worst case wastage is about
00064        32 bytes plus the remainder from a system page (the minimal
00065        mmap unit); typically 4096 or 8192 bytes.
00066 
00067   Security: static-safe; optionally more or less
00068        The "security" of malloc refers to the ability of malicious
00069        code to accentuate the effects of errors (for example, freeing
00070        space that is not currently malloc'ed or overwriting past the
00071        ends of chunks) in code that calls malloc.  This malloc
00072        guarantees not to modify any memory locations below the base of
00073        heap, i.e., static variables, even in the presence of usage
00074        errors.  The routines additionally detect most improper frees
00075        and reallocs.  All this holds as long as the static bookkeeping
00076        for malloc itself is not corrupted by some other means.  This
00077        is only one aspect of security -- these checks do not, and
00078        cannot, detect all possible programming errors.
00079 
00080        If FOOTERS is defined nonzero, then each allocated chunk
00081        carries an additional check word to verify that it was malloced
00082        from its space.  These check words are the same within each
00083        execution of a program using malloc, but differ across
00084        executions, so externally crafted fake chunks cannot be
00085        freed. This improves security by rejecting frees/reallocs that
00086        could corrupt heap memory, in addition to the checks preventing
00087        writes to statics that are always on.  This may further improve
00088        security at the expense of time and space overhead.  (Note that
00089        FOOTERS may also be worth using with MSPACES.)
00090 
00091        By default detected errors cause the program to abort (calling
00092        "abort()"). You can override this to instead proceed past
00093        errors by defining PROCEED_ON_ERROR.  In this case, a bad free
00094        has no effect, and a malloc that encounters a bad address
00095        caused by user overwrites will ignore the bad address by
00096        dropping pointers and indices to all known memory. This may
00097        be appropriate for programs that should continue if at all
00098        possible in the face of programming errors, although they may
00099        run out of memory because dropped memory is never reclaimed.
00100 
00101        If you don't like either of these options, you can define
00102        CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
00103        else. And if if you are sure that your program using malloc has
00104        no errors or vulnerabilities, you can define INSECURE to 1,
00105        which might (or might not) provide a small performance improvement.
00106 
00107   Thread-safety: NOT thread-safe unless USE_LOCKS defined
00108        When USE_LOCKS is defined, each public call to malloc, free,
00109        etc is surrounded with either a pthread mutex or a win32
00110        spinlock (depending on WIN32). This is not especially fast, and
00111        can be a major bottleneck.  It is designed only to provide
00112        minimal protection in concurrent environments, and to provide a
00113        basis for extensions.  If you are using malloc in a concurrent
00114        program, consider instead using nedmalloc
00115        (http://www.nedprod.com/programs/portable/nedmalloc/) or
00116        ptmalloc (See http://www.malloc.de), which are derived
00117        from versions of this malloc.
00118 
00119   System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
00120        This malloc can use unix sbrk or any emulation (invoked using
00121        the CALL_MORECORE macro) and/or mmap/munmap or any emulation
00122        (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
00123        memory.  On most unix systems, it tends to work best if both
00124        MORECORE and MMAP are enabled.  On Win32, it uses emulations
00125        based on VirtualAlloc. It also uses common C library functions
00126        like memset.
00127 
00128   Compliance: I believe it is compliant with the Single Unix Specification
00129        (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
00130        others as well.
00131 
00132 * Overview of algorithms
00133 
00134   This is not the fastest, most space-conserving, most portable, or
00135   most tunable malloc ever written. However it is among the fastest
00136   while also being among the most space-conserving, portable and
00137   tunable.  Consistent balance across these factors results in a good
00138   general-purpose allocator for malloc-intensive programs.
00139 
00140   In most ways, this malloc is a best-fit allocator. Generally, it
00141   chooses the best-fitting existing chunk for a request, with ties
00142   broken in approximately least-recently-used order. (This strategy
00143   normally maintains low fragmentation.) However, for requests less
00144   than 256bytes, it deviates from best-fit when there is not an
00145   exactly fitting available chunk by preferring to use space adjacent
00146   to that used for the previous small request, as well as by breaking
00147   ties in approximately most-recently-used order. (These enhance
00148   locality of series of small allocations.)  And for very large requests
00149   (>= 256Kb by default), it relies on system memory mapping
00150   facilities, if supported.  (This helps avoid carrying around and
00151   possibly fragmenting memory used only for large chunks.)
00152 
00153   All operations (except malloc_stats and mallinfo) have execution
00154   times that are bounded by a constant factor of the number of bits in
00155   a size_t, not counting any clearing in calloc or copying in realloc,
00156   or actions surrounding MORECORE and MMAP that have times
00157   proportional to the number of non-contiguous regions returned by
00158   system allocation routines, which is often just 1. In real-time
00159   applications, you can optionally suppress segment traversals using
00160   NO_SEGMENT_TRAVERSAL, which assures bounded execution even when
00161   system allocators return non-contiguous spaces, at the typical
00162   expense of carrying around more memory and increased fragmentation.
00163 
00164   The implementation is not very modular and seriously overuses
00165   macros. Perhaps someday all C compilers will do as good a job
00166   inlining modular code as can now be done by brute-force expansion,
00167   but now, enough of them seem not to.
00168 
00169   Some compilers issue a lot of warnings about code that is
00170   dead/unreachable only on some platforms, and also about intentional
00171   uses of negation on unsigned types. All known cases of each can be
00172   ignored.
00173 
00174   For a longer but out of date high-level description, see
00175      http://gee.cs.oswego.edu/dl/html/malloc.html
00176 
00177 * MSPACES
00178   If MSPACES is defined, then in addition to malloc, free, etc.,
00179   this file also defines mspace_malloc, mspace_free, etc. These
00180   are versions of malloc routines that take an "mspace" argument
00181   obtained using create_mspace, to control all internal bookkeeping.
00182   If ONLY_MSPACES is defined, only these versions are compiled.
00183   So if you would like to use this allocator for only some allocations,
00184   and your system malloc for others, you can compile with
00185   ONLY_MSPACES and then do something like...
00186     static mspace mymspace = create_mspace(0,0); // for example
00187     #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
00188 
00189   (Note: If you only need one instance of an mspace, you can instead
00190   use "USE_DL_PREFIX" to relabel the global malloc.)
00191 
00192   You can similarly create thread-local allocators by storing
00193   mspaces as thread-locals. For example:
00194     static __thread mspace tlms = 0;
00195     void*  tlmalloc(size_t bytes) {
00196       if (tlms == 0) tlms = create_mspace(0, 0);
00197       return mspace_malloc(tlms, bytes);
00198     }
00199     void  tlfree(void* mem) { mspace_free(tlms, mem); }
00200 
00201   Unless FOOTERS is defined, each mspace is completely independent.
00202   You cannot allocate from one and free to another (although
00203   conformance is only weakly checked, so usage errors are not always
00204   caught). If FOOTERS is defined, then each chunk carries around a tag
00205   indicating its originating mspace, and frees are directed to their
00206   originating spaces.
00207 
00208  -------------------------  Compile-time options ---------------------------
00209 
00210 Be careful in setting #define values for numerical constants of type
00211 size_t. On some systems, literal values are not automatically extended
00212 to size_t precision unless they are explicitly casted. You can also
00213 use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.
00214 
00215 WIN32                    default: defined if _WIN32 defined
00216   Defining WIN32 sets up defaults for MS environment and compilers.
00217   Otherwise defaults are for unix. Beware that there seem to be some
00218   cases where this malloc might not be a pure drop-in replacement for
00219   Win32 malloc: Random-looking failures from Win32 GDI API's (eg;
00220   SetDIBits()) may be due to bugs in some video driver implementations
00221   when pixel buffers are malloc()ed, and the region spans more than
00222   one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)
00223   default granularity, pixel buffers may straddle virtual allocation
00224   regions more often than when using the Microsoft allocator.  You can
00225   avoid this by using VirtualAlloc() and VirtualFree() for all pixel
00226   buffers rather than using malloc().  If this is not possible,
00227   recompile this malloc with a larger DEFAULT_GRANULARITY.
00228 
00229 MALLOC_ALIGNMENT         default: (size_t)8
00230   Controls the minimum alignment for malloc'ed chunks.  It must be a
00231   power of two and at least 8, even on machines for which smaller
00232   alignments would suffice. It may be defined as larger than this
00233   though. Note however that code and data structures are optimized for
00234   the case of 8-byte alignment.
00235 
00236 MSPACES                  default: 0 (false)
00237   If true, compile in support for independent allocation spaces.
00238   This is only supported if HAVE_MMAP is true.
00239 
00240 ONLY_MSPACES             default: 0 (false)
00241   If true, only compile in mspace versions, not regular versions.
00242 
00243 USE_LOCKS                default: 0 (false)
00244   Causes each call to each public routine to be surrounded with
00245   pthread or WIN32 mutex lock/unlock. (If set true, this can be
00246   overridden on a per-mspace basis for mspace versions.) If set to a
00247   non-zero value other than 1, locks are used, but their
00248   implementation is left out, so lock functions must be supplied manually.
00249 
00250 USE_SPIN_LOCKS           default: 1 iff USE_LOCKS and on x86 using gcc or MSC
00251   If true, uses custom spin locks for locking. This is currently
00252   supported only for x86 platforms using gcc or recent MS compilers.
00253   Otherwise, posix locks or win32 critical sections are used.
00254 
00255 FOOTERS                  default: 0
00256   If true, provide extra checking and dispatching by placing
00257   information in the footers of allocated chunks. This adds
00258   space and time overhead.
00259 
00260 INSECURE                 default: 0
00261   If true, omit checks for usage errors and heap space overwrites.
00262 
00263 USE_DL_PREFIX            default: NOT defined
00264   Causes compiler to prefix all public routines with the string 'dl'.
00265   This can be useful when you only want to use this malloc in one part
00266   of a program, using your regular system malloc elsewhere.
00267 
00268 ABORT                    default: defined as abort()
00269   Defines how to abort on failed checks.  On most systems, a failed
00270   check cannot die with an "assert" or even print an informative
00271   message, because the underlying print routines in turn call malloc,
00272   which will fail again.  Generally, the best policy is to simply call
00273   abort(). It's not very useful to do more than this because many
00274   errors due to overwriting will show up as address faults (null, odd
00275   addresses etc) rather than malloc-triggered checks, so will also
00276   abort.  Also, most compilers know that abort() does not return, so
00277   can better optimize code conditionally calling it.
00278 
00279 PROCEED_ON_ERROR           default: defined as 0 (false)
00280   Controls whether detected bad addresses cause them to bypassed
00281   rather than aborting. If set, detected bad arguments to free and
00282   realloc are ignored. And all bookkeeping information is zeroed out
00283   upon a detected overwrite of freed heap space, thus losing the
00284   ability to ever return it from malloc again, but enabling the
00285   application to proceed. If PROCEED_ON_ERROR is defined, the
00286   static variable malloc_corruption_error_count is compiled in
00287   and can be examined to see if errors have occurred. This option
00288   generates slower code than the default abort policy.
00289 
00290 DEBUG                    default: NOT defined
00291   The DEBUG setting is mainly intended for people trying to modify
00292   this code or diagnose problems when porting to new platforms.
00293   However, it may also be able to better isolate user errors than just
00294   using runtime checks.  The assertions in the check routines spell
00295   out in more detail the assumptions and invariants underlying the
00296   algorithms.  The checking is fairly extensive, and will slow down
00297   execution noticeably. Calling malloc_stats or mallinfo with DEBUG
00298   set will attempt to check every non-mmapped allocated and free chunk
00299   in the course of computing the summaries.
00300 
00301 ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
00302   Debugging assertion failures can be nearly impossible if your
00303   version of the assert macro causes malloc to be called, which will
00304   lead to a cascade of further failures, blowing the runtime stack.
00305   ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
00306   which will usually make debugging easier.
00307 
00308 MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
00309   The action to take before "return 0" when malloc fails to be able to
00310   return memory because there is none available.
00311 
00312 HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
00313   True if this system supports sbrk or an emulation of it.
00314 
00315 MORECORE                  default: sbrk
00316   The name of the sbrk-style system routine to call to obtain more
00317   memory.  See below for guidance on writing custom MORECORE
00318   functions. The type of the argument to sbrk/MORECORE varies across
00319   systems.  It cannot be size_t, because it supports negative
00320   arguments, so it is normally the signed type of the same width as
00321   size_t (sometimes declared as "intptr_t").  It doesn't much matter
00322   though. Internally, we only call it with arguments less than half
00323   the max value of a size_t, which should work across all reasonable
00324   possibilities, although sometimes generating compiler warnings.  
00325 
00326 MORECORE_CONTIGUOUS       default: 1 (true) if HAVE_MORECORE
00327   If true, take advantage of fact that consecutive calls to MORECORE
00328   with positive arguments always return contiguous increasing
00329   addresses.  This is true of unix sbrk. It does not hurt too much to
00330   set it true anyway, since malloc copes with non-contiguities.
00331   Setting it false when definitely non-contiguous saves time
00332   and possibly wasted space it would take to discover this though.
00333 
00334 MORECORE_CANNOT_TRIM      default: NOT defined
00335   True if MORECORE cannot release space back to the system when given
00336   negative arguments. This is generally necessary only if you are
00337   using a hand-crafted MORECORE function that cannot handle negative
00338   arguments.
00339 
00340 NO_SEGMENT_TRAVERSAL       default: 0
00341   If non-zero, suppresses traversals of memory segments
00342   returned by either MORECORE or CALL_MMAP. This disables
00343   merging of segments that are contiguous, and selectively
00344   releasing them to the OS if unused, but bounds execution times.
00345 
00346 HAVE_MMAP                 default: 1 (true)
00347   True if this system supports mmap or an emulation of it.  If so, and
00348   HAVE_MORECORE is not true, MMAP is used for all system
00349   allocation. If set and HAVE_MORECORE is true as well, MMAP is
00350   primarily used to directly allocate very large blocks. It is also
00351   used as a backup strategy in cases where MORECORE fails to provide
00352   space from system. Note: A single call to MUNMAP is assumed to be
00353   able to unmap memory that may have be allocated using multiple calls
00354   to MMAP, so long as they are adjacent.
00355 
00356 HAVE_MREMAP               default: 1 on linux, else 0
00357   If true realloc() uses mremap() to re-allocate large blocks and
00358   extend or shrink allocation spaces.
00359 
00360 MMAP_CLEARS               default: 1 except on WINCE.
00361   True if mmap clears memory so calloc doesn't need to. This is true
00362   for standard unix mmap using /dev/zero and on WIN32 except for WINCE.
00363 
00364 USE_BUILTIN_FFS            default: 0 (i.e., not used)
00365   Causes malloc to use the builtin ffs() function to compute indices.
00366   Some compilers may recognize and intrinsify ffs to be faster than the
00367   supplied C version. Also, the case of x86 using gcc is special-cased
00368   to an asm instruction, so is already as fast as it can be, and so
00369   this setting has no effect. Similarly for Win32 under recent MS compilers.
00370   (On most x86s, the asm version is only slightly faster than the C version.)
00371 
00372 malloc_getpagesize         default: derive from system includes, or 4096.
00373   The system page size. To the extent possible, this malloc manages
00374   memory from the system in page-size units.  This may be (and
00375   usually is) a function rather than a constant. This is ignored
00376   if WIN32, where page size is determined using getSystemInfo during
00377   initialization.
00378 
00379 USE_DEV_RANDOM             default: 0 (i.e., not used)
00380   Causes malloc to use /dev/random to initialize secure magic seed for
00381   stamping footers. Otherwise, the current time is used.
00382 
00383 NO_MALLINFO                default: 0
00384   If defined, don't compile "mallinfo". This can be a simple way
00385   of dealing with mismatches between system declarations and
00386   those in this file.
00387 
00388 MALLINFO_FIELD_TYPE        default: size_t
00389   The type of the fields in the mallinfo struct. This was originally
00390   defined as "int" in SVID etc, but is more usefully defined as
00391   size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
00392 
00393 REALLOC_ZERO_BYTES_FREES    default: not defined
00394   This should be set if a call to realloc with zero bytes should
00395   be the same as a call to free. Some people think it should. Otherwise,
00396   since this malloc returns a unique pointer for malloc(0), so does
00397   realloc(p, 0).
00398 
00399 LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
00400 LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
00401 LACKS_STDLIB_H                default: NOT defined unless on WIN32
00402   Define these if your system does not have these header files.
00403   You might need to manually insert some of the declarations they provide.
00404 
00405 DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
00406                                 system_info.dwAllocationGranularity in WIN32,
00407                                 otherwise 64K.
00408       Also settable using mallopt(M_GRANULARITY, x)
00409   The unit for allocating and deallocating memory from the system.  On
00410   most systems with contiguous MORECORE, there is no reason to
00411   make this more than a page. However, systems with MMAP tend to
00412   either require or encourage larger granularities.  You can increase
00413   this value to prevent system allocation functions to be called so
00414   often, especially if they are slow.  The value must be at least one
00415   page and must be a power of two.  Setting to 0 causes initialization
00416   to either page size or win32 region size.  (Note: In previous
00417   versions of malloc, the equivalent of this option was called
00418   "TOP_PAD")
00419 
00420 DEFAULT_TRIM_THRESHOLD    default: 2MB
00421       Also settable using mallopt(M_TRIM_THRESHOLD, x)
00422   The maximum amount of unused top-most memory to keep before
00423   releasing via malloc_trim in free().  Automatic trimming is mainly
00424   useful in long-lived programs using contiguous MORECORE.  Because
00425   trimming via sbrk can be slow on some systems, and can sometimes be
00426   wasteful (in cases where programs immediately afterward allocate
00427   more large chunks) the value should be high enough so that your
00428   overall system performance would improve by releasing this much
00429   memory.  As a rough guide, you might set to a value close to the
00430   average size of a process (program) running on your system.
00431   Releasing this much memory would allow such a process to run in
00432   memory.  Generally, it is worth tuning trim thresholds when a
00433   program undergoes phases where several large chunks are allocated
00434   and released in ways that can reuse each other's storage, perhaps
00435   mixed with phases where there are no such chunks at all. The trim
00436   value must be greater than page size to have any useful effect.  To
00437   disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
00438   some people use of mallocing a huge space and then freeing it at
00439   program startup, in an attempt to reserve system memory, doesn't
00440   have the intended effect under automatic trimming, since that memory
00441   will immediately be returned to the system.
00442 
00443 DEFAULT_MMAP_THRESHOLD       default: 256K
00444       Also settable using mallopt(M_MMAP_THRESHOLD, x)
00445   The request size threshold for using MMAP to directly service a
00446   request. Requests of at least this size that cannot be allocated
00447   using already-existing space will be serviced via mmap.  (If enough
00448   normal freed space already exists it is used instead.)  Using mmap
00449   segregates relatively large chunks of memory so that they can be
00450   individually obtained and released from the host system. A request
00451   serviced through mmap is never reused by any other request (at least
00452   not directly; the system may just so happen to remap successive
00453   requests to the same locations).  Segregating space in this way has
00454   the benefits that: Mmapped space can always be individually released
00455   back to the system, which helps keep the system level memory demands
00456   of a long-lived program low.  Also, mapped memory doesn't become
00457   `locked' between other chunks, as can happen with normally allocated
00458   chunks, which means that even trimming via malloc_trim would not
00459   release them.  However, it has the disadvantage that the space
00460   cannot be reclaimed, consolidated, and then used to service later
00461   requests, as happens with normal chunks.  The advantages of mmap
00462   nearly always outweigh disadvantages for "large" chunks, but the
00463   value of "large" may vary across systems.  The default is an
00464   empirically derived value that works well in most systems. You can
00465   disable mmap by setting to MAX_SIZE_T.
00466 
00467 MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP
00468   The number of consolidated frees between checks to release
00469   unused segments when freeing. When using non-contiguous segments,
00470   especially with multiple mspaces, checking only for topmost space
00471   doesn't always suffice to trigger trimming. To compensate for this,
00472   free() will, with a period of MAX_RELEASE_CHECK_RATE (or the
00473   current number of segments, if greater) try to release unused
00474   segments to the OS when freeing chunks that result in
00475   consolidation. The best value for this parameter is a compromise
00476   between slowing down frees with relatively costly checks that
00477   rarely trigger versus holding on to unused memory. To effectively
00478   disable, set to MAX_SIZE_T. This may lead to a very slight speed
00479   improvement at the expense of carrying around more memory.
00480 */
00481 
00482 /* Version identifier to allow people to support multiple versions */
00483 #ifndef DLMALLOC_VERSION
00484 #define DLMALLOC_VERSION 20804
00485 #endif /* DLMALLOC_VERSION */
00486 
00487 #ifndef WIN32
00488 #ifdef _WIN32
00489 #define WIN32 1
00490 #endif  /* _WIN32 */
00491 #ifdef _WIN32_WCE
00492 #define LACKS_FCNTL_H
00493 #define WIN32 1
00494 #endif /* _WIN32_WCE */
00495 #endif  /* WIN32 */
00496 #ifdef WIN32
00497 #define WIN32_LEAN_AND_MEAN
00498 #define _WIN32_WINNT 0x403
00499 #include <windows.h>
00500 #define HAVE_MMAP 1
00501 #define HAVE_MORECORE 0
00502 #define LACKS_UNISTD_H
00503 #define LACKS_SYS_PARAM_H
00504 #define LACKS_SYS_MMAN_H
00505 #define LACKS_STRING_H
00506 #define LACKS_STRINGS_H
00507 #define LACKS_SYS_TYPES_H
00508 #define LACKS_ERRNO_H
00509 #ifndef MALLOC_FAILURE_ACTION
00510 #define MALLOC_FAILURE_ACTION
00511 #endif /* MALLOC_FAILURE_ACTION */
00512 #ifdef _WIN32_WCE /* WINCE reportedly does not clear */
00513 #define MMAP_CLEARS 0
00514 #else
00515 #define MMAP_CLEARS 1
00516 #endif /* _WIN32_WCE */
00517 #endif  /* WIN32 */
00518 
00519 #if defined(DARWIN) || defined(_DARWIN)
00520 /* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
00521 #ifndef HAVE_MORECORE
00522 #define HAVE_MORECORE 0
00523 #define HAVE_MMAP 1
00524 /* OSX allocators provide 16 byte alignment */
00525 #ifndef MALLOC_ALIGNMENT
00526 #define MALLOC_ALIGNMENT ((size_t)16U)
00527 #endif
00528 #endif  /* HAVE_MORECORE */
00529 #endif  /* DARWIN */
00530 
00531 #ifndef LACKS_SYS_TYPES_H
00532 #include <sys/types.h>  /* For size_t */
00533 #endif  /* LACKS_SYS_TYPES_H */
00534 
00535 /* The maximum possible size_t value has all bits set */
00536 #define MAX_SIZE_T           (~(size_t)0)
00537 
00538 #ifndef ONLY_MSPACES
00539 #define ONLY_MSPACES 0     /* define to a value */
00540 #else
00541 #define ONLY_MSPACES 1
00542 #endif  /* ONLY_MSPACES */
00543 #ifndef MSPACES
00544 #if ONLY_MSPACES
00545 #define MSPACES 1
00546 #else   /* ONLY_MSPACES */
00547 #define MSPACES 0
00548 #endif  /* ONLY_MSPACES */
00549 #endif  /* MSPACES */
00550 #ifndef MALLOC_ALIGNMENT
00551 #define MALLOC_ALIGNMENT ((size_t)8U)
00552 #endif  /* MALLOC_ALIGNMENT */
00553 #ifndef FOOTERS
00554 #define FOOTERS 0
00555 #endif  /* FOOTERS */
00556 #ifndef ABORT
00557 #define ABORT  abort()
00558 #endif  /* ABORT */
00559 #ifndef ABORT_ON_ASSERT_FAILURE
00560 #define ABORT_ON_ASSERT_FAILURE 1
00561 #endif  /* ABORT_ON_ASSERT_FAILURE */
00562 #ifndef PROCEED_ON_ERROR
00563 #define PROCEED_ON_ERROR 0
00564 #endif  /* PROCEED_ON_ERROR */
00565 #ifndef USE_LOCKS
00566 #define USE_LOCKS 0
00567 #endif  /* USE_LOCKS */
00568 #ifndef USE_SPIN_LOCKS
00569 #if USE_LOCKS && (defined(__GNUC__) && ((defined(__i386__) || defined(__x86_64__)))) || (defined(_MSC_VER) && _MSC_VER>=1310)
00570 #define USE_SPIN_LOCKS 1
00571 #else
00572 #define USE_SPIN_LOCKS 0
00573 #endif /* USE_LOCKS && ... */
00574 #endif /* USE_SPIN_LOCKS */
00575 #ifndef INSECURE
00576 #define INSECURE 0
00577 #endif  /* INSECURE */
00578 #ifndef HAVE_MMAP
00579 #define HAVE_MMAP 1
00580 #endif  /* HAVE_MMAP */
00581 #ifndef MMAP_CLEARS
00582 #define MMAP_CLEARS 1
00583 #endif  /* MMAP_CLEARS */
00584 #ifndef HAVE_MREMAP
00585 #ifdef linux
00586 #define HAVE_MREMAP 1
00587 #else   /* linux */
00588 #define HAVE_MREMAP 0
00589 #endif  /* linux */
00590 #endif  /* HAVE_MREMAP */
00591 #ifndef MALLOC_FAILURE_ACTION
00592 #define MALLOC_FAILURE_ACTION  errno = ENOMEM;
00593 #endif  /* MALLOC_FAILURE_ACTION */
00594 #ifndef HAVE_MORECORE
00595 #if ONLY_MSPACES
00596 #define HAVE_MORECORE 0
00597 #else   /* ONLY_MSPACES */
00598 #define HAVE_MORECORE 1
00599 #endif  /* ONLY_MSPACES */
00600 #endif  /* HAVE_MORECORE */
00601 #if !HAVE_MORECORE
00602 #define MORECORE_CONTIGUOUS 0
00603 #else   /* !HAVE_MORECORE */
00604 #define MORECORE_DEFAULT sbrk
00605 #ifndef MORECORE_CONTIGUOUS
00606 #define MORECORE_CONTIGUOUS 1
00607 #endif  /* MORECORE_CONTIGUOUS */
00608 #endif  /* HAVE_MORECORE */
00609 #ifndef DEFAULT_GRANULARITY
00610 #if (MORECORE_CONTIGUOUS || defined(WIN32))
00611 #define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
00612 #else   /* MORECORE_CONTIGUOUS */
00613 #define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
00614 #endif  /* MORECORE_CONTIGUOUS */
00615 #endif  /* DEFAULT_GRANULARITY */
00616 #ifndef DEFAULT_TRIM_THRESHOLD
00617 #ifndef MORECORE_CANNOT_TRIM
00618 #define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
00619 #else   /* MORECORE_CANNOT_TRIM */
00620 #define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
00621 #endif  /* MORECORE_CANNOT_TRIM */
00622 #endif  /* DEFAULT_TRIM_THRESHOLD */
00623 #ifndef DEFAULT_MMAP_THRESHOLD
00624 #if HAVE_MMAP
00625 #define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
00626 #else   /* HAVE_MMAP */
00627 #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
00628 #endif  /* HAVE_MMAP */
00629 #endif  /* DEFAULT_MMAP_THRESHOLD */
00630 #ifndef MAX_RELEASE_CHECK_RATE
00631 #if HAVE_MMAP
00632 #define MAX_RELEASE_CHECK_RATE 4095
00633 #else
00634 #define MAX_RELEASE_CHECK_RATE MAX_SIZE_T
00635 #endif /* HAVE_MMAP */
00636 #endif /* MAX_RELEASE_CHECK_RATE */
00637 #ifndef USE_BUILTIN_FFS
00638 #define USE_BUILTIN_FFS 0
00639 #endif  /* USE_BUILTIN_FFS */
00640 #ifndef USE_DEV_RANDOM
00641 #define USE_DEV_RANDOM 0
00642 #endif  /* USE_DEV_RANDOM */
00643 #ifndef NO_MALLINFO
00644 #define NO_MALLINFO 0
00645 #endif  /* NO_MALLINFO */
00646 #ifndef MALLINFO_FIELD_TYPE
00647 #define MALLINFO_FIELD_TYPE size_t
00648 #endif  /* MALLINFO_FIELD_TYPE */
00649 #ifndef NO_SEGMENT_TRAVERSAL
00650 #define NO_SEGMENT_TRAVERSAL 0
00651 #endif /* NO_SEGMENT_TRAVERSAL */
00652 
00653 /*
00654   mallopt tuning options.  SVID/XPG defines four standard parameter
00655   numbers for mallopt, normally defined in malloc.h.  None of these
00656   are used in this malloc, so setting them has no effect. But this
00657   malloc does support the following options.
00658 */
00659 
00660 #define M_TRIM_THRESHOLD     (-1)
00661 #define M_GRANULARITY        (-2)
00662 #define M_MMAP_THRESHOLD     (-3)
00663 
00664 /* ------------------------ Mallinfo declarations ------------------------ */
00665 
00666 #if !NO_MALLINFO
00667 /*
00668   This version of malloc supports the standard SVID/XPG mallinfo
00669   routine that returns a struct containing usage properties and
00670   statistics. It should work on any system that has a
00671   /usr/include/malloc.h defining struct mallinfo.  The main
00672   declaration needed is the mallinfo struct that is returned (by-copy)
00673   by mallinfo().  The malloinfo struct contains a bunch of fields that
00674   are not even meaningful in this version of malloc.  These fields are
00675   are instead filled by mallinfo() with other numbers that might be of
00676   interest.
00677 
00678   HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
00679   /usr/include/malloc.h file that includes a declaration of struct
00680   mallinfo.  If so, it is included; else a compliant version is
00681   declared below.  These must be precisely the same for mallinfo() to
00682   work.  The original SVID version of this struct, defined on most
00683   systems with mallinfo, declares all fields as ints. But some others
00684   define as unsigned long. If your system defines the fields using a
00685   type of different width than listed here, you MUST #include your
00686   system version and #define HAVE_USR_INCLUDE_MALLOC_H.
00687 */
00688 
00689 /* #define HAVE_USR_INCLUDE_MALLOC_H */
00690 
00691 #ifdef HAVE_USR_INCLUDE_MALLOC_H
00692 #include "/usr/include/malloc.h"
00693 #else /* HAVE_USR_INCLUDE_MALLOC_H */
00694 #ifndef STRUCT_MALLINFO_DECLARED
00695 #define STRUCT_MALLINFO_DECLARED 1
00696 struct mallinfo {
00697   MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
00698   MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
00699   MALLINFO_FIELD_TYPE smblks;   /* always 0 */
00700   MALLINFO_FIELD_TYPE hblks;    /* always 0 */
00701   MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
00702   MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
00703   MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
00704   MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
00705   MALLINFO_FIELD_TYPE fordblks; /* total free space */
00706   MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
00707 };
00708 #endif /* STRUCT_MALLINFO_DECLARED */
00709 #endif /* HAVE_USR_INCLUDE_MALLOC_H */
00710 #endif /* NO_MALLINFO */
00711 
00712 /*
00713   Try to persuade compilers to inline. The most critical functions for
00714   inlining are defined as macros, so these aren't used for them.
00715 */
00716 
00717 #ifndef FORCEINLINE
00718   #if defined(__GNUC__)
00719 #define FORCEINLINE __inline __attribute__ ((always_inline))
00720   #elif defined(_MSC_VER)
00721     #define FORCEINLINE __forceinline
00722   #endif
00723 #endif
00724 #ifndef NOINLINE
00725   #if defined(__GNUC__)
00726     #define NOINLINE __attribute__ ((noinline))
00727   #elif defined(_MSC_VER)
00728     #define NOINLINE __declspec(noinline)
00729   #else
00730     #define NOINLINE
00731   #endif
00732 #endif
00733 
00734 #ifdef __cplusplus
00735 extern "C" {
00736 #ifndef FORCEINLINE
00737  #define FORCEINLINE inline
00738 #endif
00739 #endif /* __cplusplus */
00740 #ifndef FORCEINLINE
00741  #define FORCEINLINE
00742 #endif
00743 
00744 #if !ONLY_MSPACES
00745 
00746 /* ------------------- Declarations of public routines ------------------- */
00747 
00748 #ifndef USE_DL_PREFIX
00749 #define dlcalloc               calloc
00750 #define dlfree                 free
00751 #define dlmalloc               malloc
00752 #define dlmemalign             memalign
00753 #define dlrealloc              realloc
00754 #define dlvalloc               valloc
00755 #define dlpvalloc              pvalloc
00756 #define dlmallinfo             mallinfo
00757 #define dlmallopt              mallopt
00758 #define dlmalloc_trim          malloc_trim
00759 #define dlmalloc_stats         malloc_stats
00760 #define dlmalloc_usable_size   malloc_usable_size
00761 #define dlmalloc_footprint     malloc_footprint
00762 #define dlmalloc_max_footprint malloc_max_footprint
00763 #define dlindependent_calloc   independent_calloc
00764 #define dlindependent_comalloc independent_comalloc
00765 #endif /* USE_DL_PREFIX */
00766 
00767 
00768 /*
00769   malloc(size_t n)
00770   Returns a pointer to a newly allocated chunk of at least n bytes, or
00771   null if no space is available, in which case errno is set to ENOMEM
00772   on ANSI C systems.
00773 
00774   If n is zero, malloc returns a minimum-sized chunk. (The minimum
00775   size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
00776   systems.)  Note that size_t is an unsigned type, so calls with
00777   arguments that would be negative if signed are interpreted as
00778   requests for huge amounts of space, which will often fail. The
00779   maximum supported value of n differs across systems, but is in all
00780   cases less than the maximum representable value of a size_t.
00781 */
00782 void* dlmalloc(size_t);
00783 
00784 /*
00785   free(void* p)
00786   Releases the chunk of memory pointed to by p, that had been previously
00787   allocated using malloc or a related routine such as realloc.
00788   It has no effect if p is null. If p was not malloced or already
00789   freed, free(p) will by default cause the current program to abort.
00790 */
00791 void  dlfree(void*);
00792 
00793 /*
00794   calloc(size_t n_elements, size_t element_size);
00795   Returns a pointer to n_elements * element_size bytes, with all locations
00796   set to zero.
00797 */
00798 void* dlcalloc(size_t, size_t);
00799 
00800 /*
00801   realloc(void* p, size_t n)
00802   Returns a pointer to a chunk of size n that contains the same data
00803   as does chunk p up to the minimum of (n, p's size) bytes, or null
00804   if no space is available.
00805 
00806   The returned pointer may or may not be the same as p. The algorithm
00807   prefers extending p in most cases when possible, otherwise it
00808   employs the equivalent of a malloc-copy-free sequence.
00809 
00810   If p is null, realloc is equivalent to malloc.
00811 
00812   If space is not available, realloc returns null, errno is set (if on
00813   ANSI) and p is NOT freed.
00814 
00815   if n is for fewer bytes than already held by p, the newly unused
00816   space is lopped off and freed if possible.  realloc with a size
00817   argument of zero (re)allocates a minimum-sized chunk.
00818 
00819   The old unix realloc convention of allowing the last-free'd chunk
00820   to be used as an argument to realloc is not supported.
00821 */
00822 
00823 void* dlrealloc(void*, size_t);
00824 
00825 /*
00826   memalign(size_t alignment, size_t n);
00827   Returns a pointer to a newly allocated chunk of n bytes, aligned
00828   in accord with the alignment argument.
00829 
00830   The alignment argument should be a power of two. If the argument is
00831   not a power of two, the nearest greater power is used.
00832   8-byte alignment is guaranteed by normal malloc calls, so don't
00833   bother calling memalign with an argument of 8 or less.
00834 
00835   Overreliance on memalign is a sure way to fragment space.
00836 */
00837 void* dlmemalign(size_t, size_t);
00838 
00839 /*
00840   valloc(size_t n);
00841   Equivalent to memalign(pagesize, n), where pagesize is the page
00842   size of the system. If the pagesize is unknown, 4096 is used.
00843 */
00844 void* dlvalloc(size_t);
00845 
00846 /*
00847   mallopt(int parameter_number, int parameter_value)
00848   Sets tunable parameters The format is to provide a
00849   (parameter-number, parameter-value) pair.  mallopt then sets the
00850   corresponding parameter to the argument value if it can (i.e., so
00851   long as the value is meaningful), and returns 1 if successful else
00852   0.  To workaround the fact that mallopt is specified to use int, 
00853   not size_t parameters, the value -1 is specially treated as the 
00854   maximum unsigned size_t value.
00855 
00856   SVID/XPG/ANSI defines four standard param numbers for mallopt,
00857   normally defined in malloc.h.  None of these are use in this malloc,
00858   so setting them has no effect. But this malloc also supports other
00859   options in mallopt. See below for details.  Briefly, supported
00860   parameters are as follows (listed defaults are for "typical"
00861   configurations).
00862 
00863   Symbol            param #  default    allowed param values
00864   M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1 disables)
00865   M_GRANULARITY        -2     page size   any power of 2 >= page size
00866   M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
00867 */
00868 int dlmallopt(int, int);
00869 
00870 /*
00871   malloc_footprint();
00872   Returns the number of bytes obtained from the system.  The total
00873   number of bytes allocated by malloc, realloc etc., is less than this
00874   value. Unlike mallinfo, this function returns only a precomputed
00875   result, so can be called frequently to monitor memory consumption.
00876   Even if locks are otherwise defined, this function does not use them,
00877   so results might not be up to date.
00878 */
00879 size_t dlmalloc_footprint(void);
00880 
00881 /*
00882   malloc_max_footprint();
00883   Returns the maximum number of bytes obtained from the system. This
00884   value will be greater than current footprint if deallocated space
00885   has been reclaimed by the system. The peak number of bytes allocated
00886   by malloc, realloc etc., is less than this value. Unlike mallinfo,
00887   this function returns only a precomputed result, so can be called
00888   frequently to monitor memory consumption.  Even if locks are
00889   otherwise defined, this function does not use them, so results might
00890   not be up to date.
00891 */
00892 size_t dlmalloc_max_footprint(void);
00893 
00894 #if !NO_MALLINFO
00895 /*
00896   mallinfo()
00897   Returns (by copy) a struct containing various summary statistics:
00898 
00899   arena:     current total non-mmapped bytes allocated from system
00900   ordblks:   the number of free chunks
00901   smblks:    always zero.
00902   hblks:     current number of mmapped regions
00903   hblkhd:    total bytes held in mmapped regions
00904   usmblks:   the maximum total allocated space. This will be greater
00905                 than current total if trimming has occurred.
00906   fsmblks:   always zero
00907   uordblks:  current total allocated space (normal or mmapped)
00908   fordblks:  total free space
00909   keepcost:  the maximum number of bytes that could ideally be released
00910                back to system via malloc_trim. ("ideally" means that
00911                it ignores page restrictions etc.)
00912 
00913   Because these fields are ints, but internal bookkeeping may
00914   be kept as longs, the reported values may wrap around zero and
00915   thus be inaccurate.
00916 */
00917 struct mallinfo dlmallinfo(void);
00918 #endif /* NO_MALLINFO */
00919 
00920 /*
00921   independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
00922 
00923   independent_calloc is similar to calloc, but instead of returning a
00924   single cleared space, it returns an array of pointers to n_elements
00925   independent elements that can hold contents of size elem_size, each
00926   of which starts out cleared, and can be independently freed,
00927   realloc'ed etc. The elements are guaranteed to be adjacently
00928   allocated (this is not guaranteed to occur with multiple callocs or
00929   mallocs), which may also improve cache locality in some
00930   applications.
00931 
00932   The "chunks" argument is optional (i.e., may be null, which is
00933   probably the most typical usage). If it is null, the returned array
00934   is itself dynamically allocated and should also be freed when it is
00935   no longer needed. Otherwise, the chunks array must be of at least
00936   n_elements in length. It is filled in with the pointers to the
00937   chunks.
00938 
00939   In either case, independent_calloc returns this pointer array, or
00940   null if the allocation failed.  If n_elements is zero and "chunks"
00941   is null, it returns a chunk representing an array with zero elements
00942   (which should be freed if not wanted).
00943 
00944   Each element must be individually freed when it is no longer
00945   needed. If you'd like to instead be able to free all at once, you
00946   should instead use regular calloc and assign pointers into this
00947   space to represent elements.  (In this case though, you cannot
00948   independently free elements.)
00949 
00950   independent_calloc simplifies and speeds up implementations of many
00951   kinds of pools.  It may also be useful when constructing large data
00952   structures that initially have a fixed number of fixed-sized nodes,
00953   but the number is not known at compile time, and some of the nodes
00954   may later need to be freed. For example:
00955 
00956   struct Node { int item; struct Node* next; };
00957 
00958   struct Node* build_list() {
00959     struct Node** pool;
00960     int n = read_number_of_nodes_needed();
00961     if (n <= 0) return 0;
00962     pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
00963     if (pool == 0) die();
00964     // organize into a linked list...
00965     struct Node* first = pool[0];
00966     for (i = 0; i < n-1; ++i)
00967       pool[i]->next = pool[i+1];
00968     free(pool);     // Can now free the array (or not, if it is needed later)
00969     return first;
00970   }
00971 */
00972 void** dlindependent_calloc(size_t, size_t, void**);
00973 
00974 /*
00975   independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
00976 
00977   independent_comalloc allocates, all at once, a set of n_elements
00978   chunks with sizes indicated in the "sizes" array.    It returns
00979   an array of pointers to these elements, each of which can be
00980   independently freed, realloc'ed etc. The elements are guaranteed to
00981   be adjacently allocated (this is not guaranteed to occur with
00982   multiple callocs or mallocs), which may also improve cache locality
00983   in some applications.
00984 
00985   The "chunks" argument is optional (i.e., may be null). If it is null
00986   the returned array is itself dynamically allocated and should also
00987   be freed when it is no longer needed. Otherwise, the chunks array
00988   must be of at least n_elements in length. It is filled in with the
00989   pointers to the chunks.
00990 
00991   In either case, independent_comalloc returns this pointer array, or
00992   null if the allocation failed.  If n_elements is zero and chunks is
00993   null, it returns a chunk representing an array with zero elements
00994   (which should be freed if not wanted).
00995 
00996   Each element must be individually freed when it is no longer
00997   needed. If you'd like to instead be able to free all at once, you
00998   should instead use a single regular malloc, and assign pointers at
00999   particular offsets in the aggregate space. (In this case though, you
01000   cannot independently free elements.)
01001 
01002   independent_comallac differs from independent_calloc in that each
01003   element may have a different size, and also that it does not
01004   automatically clear elements.
01005 
01006   independent_comalloc can be used to speed up allocation in cases
01007   where several structs or objects must always be allocated at the
01008   same time.  For example:
01009 
01010   struct Head { ... }
01011   struct Foot { ... }
01012 
01013   void send_message(char* msg) {
01014     int msglen = strlen(msg);
01015     size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
01016     void* chunks[3];
01017     if (independent_comalloc(3, sizes, chunks) == 0)
01018       die();
01019     struct Head* head = (struct Head*)(chunks[0]);
01020     char*        body = (char*)(chunks[1]);
01021     struct Foot* foot = (struct Foot*)(chunks[2]);
01022     // ...
01023   }
01024 
01025   In general though, independent_comalloc is worth using only for
01026   larger values of n_elements. For small values, you probably won't
01027   detect enough difference from series of malloc calls to bother.
01028 
01029   Overuse of independent_comalloc can increase overall memory usage,
01030   since it cannot reuse existing noncontiguous small chunks that
01031   might be available for some of the elements.
01032 */
01033 void** dlindependent_comalloc(size_t, size_t*, void**);
01034 
01035 
01036 /*
01037   pvalloc(size_t n);
01038   Equivalent to valloc(minimum-page-that-holds(n)), that is,
01039   round up n to nearest pagesize.
01040  */
01041 void*  dlpvalloc(size_t);
01042 
01043 /*
01044   malloc_trim(size_t pad);
01045 
01046   If possible, gives memory back to the system (via negative arguments
01047   to sbrk) if there is unused memory at the `high' end of the malloc
01048   pool or in unused MMAP segments. You can call this after freeing
01049   large blocks of memory to potentially reduce the system-level memory
01050   requirements of a program. However, it cannot guarantee to reduce
01051   memory. Under some allocation patterns, some large free blocks of
01052   memory will be locked between two used chunks, so they cannot be
01053   given back to the system.
01054 
01055   The `pad' argument to malloc_trim represents the amount of free
01056   trailing space to leave untrimmed. If this argument is zero, only
01057   the minimum amount of memory to maintain internal data structures
01058   will be left. Non-zero arguments can be supplied to maintain enough
01059   trailing space to service future expected allocations without having
01060   to re-obtain memory from the system.
01061 
01062   Malloc_trim returns 1 if it actually released any memory, else 0.
01063 */
01064 int  dlmalloc_trim(size_t);
01065 
01066 /*
01067   malloc_stats();
01068   Prints on stderr the amount of space obtained from the system (both
01069   via sbrk and mmap), the maximum amount (which may be more than
01070   current if malloc_trim and/or munmap got called), and the current
01071   number of bytes allocated via malloc (or realloc, etc) but not yet
01072   freed. Note that this is the number of bytes allocated, not the
01073   number requested. It will be larger than the number requested
01074   because of alignment and bookkeeping overhead. Because it includes
01075   alignment wastage as being in use, this figure may be greater than
01076   zero even when no user-level chunks are allocated.
01077 
01078   The reported current and maximum system memory can be inaccurate if
01079   a program makes other calls to system memory allocation functions
01080   (normally sbrk) outside of malloc.
01081 
01082   malloc_stats prints only the most commonly interesting statistics.
01083   More information can be obtained by calling mallinfo.
01084 */
01085 void  dlmalloc_stats(void);
01086 
01087 #endif /* ONLY_MSPACES */
01088 
01089 /*
01090   malloc_usable_size(void* p);
01091 
01092   Returns the number of bytes you can actually use in
01093   an allocated chunk, which may be more than you requested (although
01094   often not) due to alignment and minimum size constraints.
01095   You can use this many bytes without worrying about
01096   overwriting other allocated objects. This is not a particularly great
01097   programming practice. malloc_usable_size can be more useful in
01098   debugging and assertions, for example:
01099 
01100   p = malloc(n);
01101   assert(malloc_usable_size(p) >= 256);
01102 */
01103 size_t dlmalloc_usable_size(void*);
01104 
01105 
01106 #if MSPACES
01107 
01108 /*
01109   mspace is an opaque type representing an independent
01110   region of space that supports mspace_malloc, etc.
01111 */
01112 typedef void* mspace;
01113 
01114 /*
01115   create_mspace creates and returns a new independent space with the
01116   given initial capacity, or, if 0, the default granularity size.  It
01117   returns null if there is no system memory available to create the
01118   space.  If argument locked is non-zero, the space uses a separate
01119   lock to control access. The capacity of the space will grow
01120   dynamically as needed to service mspace_malloc requests.  You can
01121   control the sizes of incremental increases of this space by
01122   compiling with a different DEFAULT_GRANULARITY or dynamically
01123   setting with mallopt(M_GRANULARITY, value).
01124 */
01125 mspace create_mspace(size_t capacity, int locked);
01126 
01127 /*
01128   destroy_mspace destroys the given space, and attempts to return all
01129   of its memory back to the system, returning the total number of
01130   bytes freed. After destruction, the results of access to all memory
01131   used by the space become undefined.
01132 */
01133 size_t destroy_mspace(mspace msp);
01134 
01135 /*
01136   create_mspace_with_base uses the memory supplied as the initial base
01137   of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
01138   space is used for bookkeeping, so the capacity must be at least this
01139   large. (Otherwise 0 is returned.) When this initial space is
01140   exhausted, additional memory will be obtained from the system.
01141   Destroying this space will deallocate all additionally allocated
01142   space (if possible) but not the initial base.
01143 */
01144 mspace create_mspace_with_base(void* base, size_t capacity, int locked);
01145 
01146 /*
01147   mspace_mmap_large_chunks controls whether requests for large chunks
01148   are allocated in their own mmapped regions, separate from others in
01149   this mspace. By default this is enabled, which reduces
01150   fragmentation. However, such chunks are not necessarily released to
01151   the system upon destroy_mspace.  Disabling by setting to false may
01152   increase fragmentation, but avoids leakage when relying on
01153   destroy_mspace to release all memory allocated using this space.
01154 */
01155 int mspace_mmap_large_chunks(mspace msp, int enable);
01156 
01157 
01158 /*
01159   mspace_malloc behaves as malloc, but operates within
01160   the given space.
01161 */
01162 void* mspace_malloc(mspace msp, size_t bytes);
01163 
01164 /*
01165   mspace_free behaves as free, but operates within
01166   the given space.
01167 
01168   If compiled with FOOTERS==1, mspace_free is not actually needed.
01169   free may be called instead of mspace_free because freed chunks from
01170   any space are handled by their originating spaces.
01171 */
01172 void mspace_free(mspace msp, void* mem);
01173 
01174 /*
01175   mspace_realloc behaves as realloc, but operates within
01176   the given space.
01177 
01178   If compiled with FOOTERS==1, mspace_realloc is not actually
01179   needed.  realloc may be called instead of mspace_realloc because
01180   realloced chunks from any space are handled by their originating
01181   spaces.
01182 */
01183 void* mspace_realloc(mspace msp, void* mem, size_t newsize);
01184 
01185 /*
01186   mspace_calloc behaves as calloc, but operates within
01187   the given space.
01188 */
01189 void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
01190 
01191 /*
01192   mspace_memalign behaves as memalign, but operates within
01193   the given space.
01194 */
01195 void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
01196 
01197 /*
01198   mspace_independent_calloc behaves as independent_calloc, but
01199   operates within the given space.
01200 */
01201 void** mspace_independent_calloc(mspace msp, size_t n_elements,
01202                                  size_t elem_size, void* chunks[]);
01203 
01204 /*
01205   mspace_independent_comalloc behaves as independent_comalloc, but
01206   operates within the given space.
01207 */
01208 void** mspace_independent_comalloc(mspace msp, size_t n_elements,
01209                                    size_t sizes[], void* chunks[]);
01210 
01211 /*
01212   mspace_footprint() returns the number of bytes obtained from the
01213   system for this space.
01214 */
01215 size_t mspace_footprint(mspace msp);
01216 
01217 /*
01218   mspace_max_footprint() returns the peak number of bytes obtained from the
01219   system for this space.
01220 */
01221 size_t mspace_max_footprint(mspace msp);
01222 
01223 
01224 #if !NO_MALLINFO
01225 /*
01226   mspace_mallinfo behaves as mallinfo, but reports properties of
01227   the given space.
01228 */
01229 struct mallinfo mspace_mallinfo(mspace msp);
01230 #endif /* NO_MALLINFO */
01231 
01232 /*
01233   malloc_usable_size(void* p) behaves the same as malloc_usable_size;
01234 */
01235   size_t mspace_usable_size(void* mem);
01236 
01237 /*
01238   mspace_malloc_stats behaves as malloc_stats, but reports
01239   properties of the given space.
01240 */
01241 void mspace_malloc_stats(mspace msp);
01242 
01243 /*
01244   mspace_trim behaves as malloc_trim, but
01245   operates within the given space.
01246 */
01247 int mspace_trim(mspace msp, size_t pad);
01248 
01249 /*
01250   An alias for mallopt.
01251 */
01252 int mspace_mallopt(int, int);
01253 
01254 #endif /* MSPACES */
01255 
01256 #ifdef __cplusplus
01257 };  /* end of extern "C" */
01258 #endif /* __cplusplus */
01259 
01260 /*
01261   ========================================================================
01262   To make a fully customizable malloc.h header file, cut everything
01263   above this line, put into file malloc.h, edit to suit, and #include it
01264   on the next line, as well as in programs that use this malloc.
01265   ========================================================================
01266 */
01267 
01268 /* #include "malloc.h" */
01269 
01270 /*------------------------------ internal #includes ---------------------- */
01271 
01272 #ifdef WIN32
01273 #pragma warning( disable : 4146 ) /* no "unsigned" warnings */
01274 #endif /* WIN32 */
01275 
01276 #include <stdio.h>       /* for printing in malloc_stats */
01277 
01278 #ifndef LACKS_ERRNO_H
01279 #include <errno.h>       /* for MALLOC_FAILURE_ACTION */
01280 #endif /* LACKS_ERRNO_H */
01281 #if FOOTERS
01282 #include <time.h>        /* for magic initialization */
01283 #endif /* FOOTERS */
01284 #ifndef LACKS_STDLIB_H
01285 #include <stdlib.h>      /* for abort() */
01286 #endif /* LACKS_STDLIB_H */
01287 #ifdef DEBUG
01288 #if ABORT_ON_ASSERT_FAILURE
01289 #define assert(x) if(!(x)) ABORT
01290 #else /* ABORT_ON_ASSERT_FAILURE */
01291 #include <assert.h>
01292 #endif /* ABORT_ON_ASSERT_FAILURE */
01293 #else  /* DEBUG */
01294 #ifndef assert
01295 #define assert(x)
01296 #endif
01297 #define DEBUG 0
01298 #endif /* DEBUG */
01299 #ifndef LACKS_STRING_H
01300 #include <string.h>      /* for memset etc */
01301 #endif  /* LACKS_STRING_H */
01302 #if USE_BUILTIN_FFS
01303 #ifndef LACKS_STRINGS_H
01304 #include <strings.h>     /* for ffs */
01305 #endif /* LACKS_STRINGS_H */
01306 #endif /* USE_BUILTIN_FFS */
01307 #if HAVE_MMAP
01308 #ifndef LACKS_SYS_MMAN_H
01309 #include <sys/mman.h>    /* for mmap */
01310 #endif /* LACKS_SYS_MMAN_H */
01311 #ifndef LACKS_FCNTL_H
01312 #include <fcntl.h>
01313 #endif /* LACKS_FCNTL_H */
01314 #endif /* HAVE_MMAP */
01315 #ifndef LACKS_UNISTD_H
01316 #include <unistd.h>     /* for sbrk, sysconf */
01317 #else /* LACKS_UNISTD_H */
01318 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
01319 extern void*     sbrk(ptrdiff_t);
01320 #endif /* FreeBSD etc */
01321 #endif /* LACKS_UNISTD_H */
01322 
01323 /* Declarations for locking */
01324 #if USE_LOCKS
01325 #ifndef WIN32
01326 #include <pthread.h>
01327 #if defined (__SVR4) && defined (__sun)  /* solaris */
01328 #include <thread.h>
01329 #endif /* solaris */
01330 #else
01331 #ifndef _M_AMD64
01332 /* These are already defined on AMD64 builds */
01333 #ifdef __cplusplus
01334 extern "C" {
01335 #endif /* __cplusplus */
01336 LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);
01337 LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
01338 #ifdef __cplusplus
01339 }
01340 #endif /* __cplusplus */
01341 #endif /* _M_AMD64 */
01342 #pragma intrinsic (_InterlockedCompareExchange)
01343 #pragma intrinsic (_InterlockedExchange)
01344 #define interlockedcompareexchange _InterlockedCompareExchange
01345 #define interlockedexchange _InterlockedExchange
01346 #endif /* Win32 */
01347 #endif /* USE_LOCKS */
01348 
01349 /* Declarations for bit scanning on win32 */
01350 #if defined(_MSC_VER) && _MSC_VER>=1300
01351 #ifndef BitScanForward  /* Try to avoid pulling in WinNT.h */
01352 #ifdef __cplusplus
01353 extern "C" {
01354 #endif /* __cplusplus */
01355 unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
01356 unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
01357 #ifdef __cplusplus
01358 }
01359 #endif /* __cplusplus */
01360 
01361 #define BitScanForward _BitScanForward
01362 #define BitScanReverse _BitScanReverse
01363 #pragma intrinsic(_BitScanForward)
01364 #pragma intrinsic(_BitScanReverse)
01365 #endif /* BitScanForward */
01366 #endif /* defined(_MSC_VER) && _MSC_VER>=1300 */
01367 
01368 #ifndef WIN32
01369 #ifndef malloc_getpagesize
01370 #  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
01371 #    ifndef _SC_PAGE_SIZE
01372 #      define _SC_PAGE_SIZE _SC_PAGESIZE
01373 #    endif
01374 #  endif
01375 #  ifdef _SC_PAGE_SIZE
01376 #    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
01377 #  else
01378 #    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
01379        extern size_t getpagesize();
01380 #      define malloc_getpagesize getpagesize()
01381 #    else
01382 #      ifdef WIN32 /* use supplied emulation of getpagesize */
01383 #        define malloc_getpagesize getpagesize()
01384 #      else
01385 #        ifndef LACKS_SYS_PARAM_H
01386 #          include <sys/param.h>
01387 #        endif
01388 #        ifdef EXEC_PAGESIZE
01389 #          define malloc_getpagesize EXEC_PAGESIZE
01390 #        else
01391 #          ifdef NBPG
01392 #            ifndef CLSIZE
01393 #              define malloc_getpagesize NBPG
01394 #            else
01395 #              define malloc_getpagesize (NBPG * CLSIZE)
01396 #            endif
01397 #          else
01398 #            ifdef NBPC
01399 #              define malloc_getpagesize NBPC
01400 #            else
01401 #              ifdef PAGESIZE
01402 #                define malloc_getpagesize PAGESIZE
01403 #              else /* just guess */
01404 #                define malloc_getpagesize ((size_t)4096U)
01405 #              endif
01406 #            endif
01407 #          endif
01408 #        endif
01409 #      endif
01410 #    endif
01411 #  endif
01412 #endif
01413 #endif
01414 
01415 
01416 
01417 /* ------------------- size_t and alignment properties -------------------- */
01418 
01419 /* The byte and bit size of a size_t */
01420 #define SIZE_T_SIZE         (sizeof(size_t))
01421 #define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
01422 
01423 /* Some constants coerced to size_t */
01424 /* Annoying but necessary to avoid errors on some platforms */
01425 #define SIZE_T_ZERO         ((size_t)0)
01426 #define SIZE_T_ONE          ((size_t)1)
01427 #define SIZE_T_TWO          ((size_t)2)
01428 #define SIZE_T_FOUR         ((size_t)4)
01429 #define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
01430 #define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
01431 #define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
01432 #define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
01433 
01434 /* The bit mask value corresponding to MALLOC_ALIGNMENT */
01435 #define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
01436 
01437 /* True if address a has acceptable alignment */
01438 #define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
01439 
01440 /* the number of bytes to offset an address to align it */
01441 #define align_offset(A)\
01442  ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
01443   ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
01444 
01445 /* -------------------------- MMAP preliminaries ------------------------- */
01446 
01447 /*
01448    If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
01449    checks to fail so compiler optimizer can delete code rather than
01450    using so many "#if"s.
01451 */
01452 
01453 
01454 /* MORECORE and MMAP must return MFAIL on failure */
01455 #define MFAIL                ((void*)(MAX_SIZE_T))
01456 #define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
01457 
01458 #if HAVE_MMAP
01459 
01460 #ifndef WIN32
01461 #define MUNMAP_DEFAULT(a, s)  munmap((a), (s))
01462 #define MMAP_PROT            (PROT_READ|PROT_WRITE)
01463 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
01464 #define MAP_ANONYMOUS        MAP_ANON
01465 #endif /* MAP_ANON */
01466 #ifdef MAP_ANONYMOUS
01467 #define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
01468 #define MMAP_DEFAULT(s)       mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
01469 #else /* MAP_ANONYMOUS */
01470 /*
01471    Nearly all versions of mmap support MAP_ANONYMOUS, so the following
01472    is unlikely to be needed, but is supplied just in case.
01473 */
01474 #define MMAP_FLAGS           (MAP_PRIVATE)
01475 static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
01476 #define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \
01477            (dev_zero_fd = open("/dev/zero", O_RDWR), \
01478             mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
01479             mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
01480 #endif /* MAP_ANONYMOUS */
01481 
01482 #define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)
01483 
01484 #else /* WIN32 */
01485 
01486 /* Win32 MMAP via VirtualAlloc */
01487 static FORCEINLINE void* win32mmap(size_t size) {
01488   void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
01489   return (ptr != 0)? ptr: MFAIL;
01490 }
01491 
01492 /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
01493 static FORCEINLINE void* win32direct_mmap(size_t size) {
01494   void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
01495                            PAGE_READWRITE);
01496   return (ptr != 0)? ptr: MFAIL;
01497 }
01498 
01499 /* This function supports releasing coalesed segments */
01500 static FORCEINLINE int win32munmap(void* ptr, size_t size) {
01501   MEMORY_BASIC_INFORMATION minfo;
01502   char* cptr = (char*)ptr;
01503   while (size) {
01504     if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
01505       return -1;
01506     if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
01507         minfo.State != MEM_COMMIT || minfo.RegionSize > size)
01508       return -1;
01509     if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
01510       return -1;
01511     cptr += minfo.RegionSize;
01512     size -= minfo.RegionSize;
01513   }
01514   return 0;
01515 }
01516 
01517 #define MMAP_DEFAULT(s)             win32mmap(s)
01518 #define MUNMAP_DEFAULT(a, s)        win32munmap((a), (s))
01519 #define DIRECT_MMAP_DEFAULT(s)      win32direct_mmap(s)
01520 #endif /* WIN32 */
01521 #endif /* HAVE_MMAP */
01522 
01523 #if HAVE_MREMAP
01524 #ifndef WIN32
01525 #define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
01526 #endif /* WIN32 */
01527 #endif /* HAVE_MREMAP */
01528 
01529 
01533 #if HAVE_MORECORE
01534     #ifdef MORECORE
01535         #define CALL_MORECORE(S)    MORECORE(S)
01536     #else  /* MORECORE */
01537         #define CALL_MORECORE(S)    MORECORE_DEFAULT(S)
01538     #endif /* MORECORE */
01539 #else  /* HAVE_MORECORE */
01540     #define CALL_MORECORE(S)        MFAIL
01541 #endif /* HAVE_MORECORE */
01542 
01546 #if HAVE_MMAP
01547     #define IS_MMAPPED_BIT          (SIZE_T_ONE)
01548     #define USE_MMAP_BIT            (SIZE_T_ONE)
01549 
01550     #ifdef MMAP
01551         #define CALL_MMAP(s)        MMAP(s)
01552     #else /* MMAP */
01553         #define CALL_MMAP(s)        MMAP_DEFAULT(s)
01554     #endif /* MMAP */
01555     #ifdef MUNMAP
01556         #define CALL_MUNMAP(a, s)   MUNMAP((a), (s))
01557     #else /* MUNMAP */
01558         #define CALL_MUNMAP(a, s)   MUNMAP_DEFAULT((a), (s))
01559     #endif /* MUNMAP */
01560     #ifdef DIRECT_MMAP
01561         #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
01562     #else /* DIRECT_MMAP */
01563         #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)
01564     #endif /* DIRECT_MMAP */
01565 #else  /* HAVE_MMAP */
01566     #define IS_MMAPPED_BIT          (SIZE_T_ZERO)
01567     #define USE_MMAP_BIT            (SIZE_T_ZERO)
01568     
01569     #define MMAP(s)                 MFAIL
01570     #define MUNMAP(a, s)            (-1)
01571     #define DIRECT_MMAP(s)          MFAIL
01572     #define CALL_DIRECT_MMAP(s)     DIRECT_MMAP(s)
01573     #define CALL_MMAP(s)            MMAP(s)
01574     #define CALL_MUNMAP(a, s)       MUNMAP((a), (s))
01575 #endif /* HAVE_MMAP */
01576 
01580 #if HAVE_MMAP && HAVE_MREMAP
01581     #ifdef MREMAP
01582         #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))
01583     #else /* MREMAP */
01584         #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))
01585     #endif /* MREMAP */
01586 #else  /* HAVE_MMAP && HAVE_MREMAP */
01587     #define CALL_MREMAP(addr, osz, nsz, mv)     MFAIL
01588 #endif /* HAVE_MMAP && HAVE_MREMAP */
01589 
01590 /* mstate bit set if continguous morecore disabled or failed */
01591 #define USE_NONCONTIGUOUS_BIT (4U)
01592 
01593 /* segment bit set in create_mspace_with_base */
01594 #define EXTERN_BIT            (8U)
01595 
01596 
01597 /* --------------------------- Lock preliminaries ------------------------ */
01598 
01599 /*
01600   When locks are defined, there is one global lock, plus
01601   one per-mspace lock.
01602 
01603   The global lock_ensures that mparams.magic and other unique
01604   mparams values are initialized only once. It also protects
01605   sequences of calls to MORECORE.  In many cases sys_alloc requires
01606   two calls, that should not be interleaved with calls by other
01607   threads.  This does not protect against direct calls to MORECORE
01608   by other threads not using this lock, so there is still code to
01609   cope the best we can on interference.
01610   
01611   Per-mspace locks surround calls to malloc, free, etc.  To enable use
01612   in layered extensions, per-mspace locks are reentrant.
01613 
01614   Because lock-protected regions generally have bounded times, it is
01615   OK to use the supplied simple spinlocks in the custom versions for
01616   x86.
01617 
01618   If USE_LOCKS is > 1, the definitions of lock routines here are
01619   bypassed, in which case you will need to define at least
01620   INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and possibly TRY_LOCK
01621   (which is not used in this malloc, but commonly needed in
01622   extensions.)
01623 */
01624 
01625 #if USE_LOCKS == 1
01626 
01627 #if USE_SPIN_LOCKS
01628 #ifndef WIN32
01629 
01630 /* Custom pthread-style spin locks on x86 and x64 for gcc */
01631 struct pthread_mlock_t {
01632   volatile unsigned int l;
01633   volatile unsigned int c;
01634   volatile pthread_t threadid;
01635 };
01636 #define MLOCK_T struct        pthread_mlock_t
01637 #define CURRENT_THREAD        pthread_self()
01638 #define INITIAL_LOCK(sl)      (memset(sl, 0, sizeof(MLOCK_T)), 0)
01639 #define ACQUIRE_LOCK(sl)      pthread_acquire_lock(sl)
01640 #define RELEASE_LOCK(sl)      pthread_release_lock(sl)
01641 #define TRY_LOCK(sl)          pthread_try_lock(sl)
01642 #define SPINS_PER_YIELD       63
01643 
01644 static MLOCK_T malloc_global_mutex = { 0, 0, 0};
01645 
01646 static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) {
01647   int spins = 0;
01648   volatile unsigned int* lp = &sl->l;
01649   for (;;) {
01650     if (*lp != 0) {
01651       if (sl->threadid == CURRENT_THREAD) {
01652         ++sl->c;
01653         return 0;
01654       }
01655     }
01656     else {
01657       /* place args to cmpxchgl in locals to evade oddities in some gccs */
01658       int cmp = 0;
01659       int val = 1;
01660       int ret;
01661       __asm__ __volatile__  ("lock; cmpxchgl %1, %2"             
01662                              : "=a" (ret)               
01663                              : "r" (val), "m" (*(lp)), "0"(cmp) 
01664                              : "memory", "cc");
01665       if (!ret) {
01666         assert(!sl->threadid);
01667         sl->c = 1;
01668         sl->threadid = CURRENT_THREAD;
01669         return 0;
01670       }
01671       if ((++spins & SPINS_PER_YIELD) == 0) {
01672 #if defined (__SVR4) && defined (__sun) /* solaris */
01673         thr_yield();
01674 #else
01675 #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
01676         sched_yield();
01677 #else  /* no-op yield on unknown systems */
01678         ;
01679 #endif /* __linux__ || __FreeBSD__ || __APPLE__ */
01680 #endif /* solaris */
01681       }
01682     }
01683   }
01684 }
01685 
01686 static FORCEINLINE void pthread_release_lock (MLOCK_T *sl) {
01687   assert(sl->l != 0);
01688   assert(sl->threadid == CURRENT_THREAD);
01689   if (--sl->c == 0) {
01690     sl->threadid = 0;
01691     volatile unsigned int* lp = &sl->l;
01692     int prev = 0;
01693     int ret;
01694     __asm__ __volatile__ ("lock; xchgl %0, %1"
01695                           : "=r" (ret)
01696                           : "m" (*(lp)), "0"(prev)
01697                           : "memory");
01698   }
01699 }
01700 
01701 static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) {
01702   volatile unsigned int* lp = &sl->l;
01703   if (*lp != 0) {
01704       if (sl->threadid == CURRENT_THREAD) {
01705         ++sl->c;
01706         return 1;
01707       }
01708   }
01709   else {
01710     int cmp = 0;
01711     int val = 1;
01712     int ret;
01713     __asm__ __volatile__  ("lock; cmpxchgl %1, %2"             
01714                            : "=a" (ret)               
01715                            : "r" (val), "m" (*(lp)), "0"(cmp) 
01716                            : "memory", "cc");
01717     if (!ret) {
01718       assert(!sl->threadid);
01719       sl->c = 1;
01720       sl->threadid = CURRENT_THREAD;
01721       return 1;
01722     }
01723   }
01724   return 0;
01725 }
01726 
01727 
01728 #else /* WIN32 */
01729 /* Custom win32-style spin locks on x86 and x64 for MSC */
01730 struct win32_mlock_t
01731 {
01732   volatile long l;
01733   volatile unsigned int c;
01734   volatile long threadid;
01735 };
01736 
01737 #define MLOCK_T               struct win32_mlock_t
01738 #define CURRENT_THREAD        win32_getcurrentthreadid()
01739 #define INITIAL_LOCK(sl)      (memset(sl, 0, sizeof(MLOCK_T)), 0)
01740 #define ACQUIRE_LOCK(sl)      win32_acquire_lock(sl)
01741 #define RELEASE_LOCK(sl)      win32_release_lock(sl)
01742 #define TRY_LOCK(sl)          win32_try_lock(sl)
01743 #define SPINS_PER_YIELD       63
01744 
01745 static MLOCK_T malloc_global_mutex = { 0, 0, 0};
01746 
01747 static FORCEINLINE long win32_getcurrentthreadid() {
01748 #ifdef _MSC_VER
01749 #if defined(_M_IX86)
01750   long *threadstruct=(long *)__readfsdword(0x18);
01751   long threadid=threadstruct[0x24/sizeof(long)];
01752   return threadid;
01753 #elif defined(_M_X64)
01754   /* todo */
01755   return GetCurrentThreadId();
01756 #else
01757   return GetCurrentThreadId();
01758 #endif
01759 #else
01760   return GetCurrentThreadId();
01761 #endif
01762 }
01763 
01764 static FORCEINLINE int win32_acquire_lock (MLOCK_T *sl) {
01765   int spins = 0;
01766   for (;;) {
01767     if (sl->l != 0) {
01768       if (sl->threadid == CURRENT_THREAD) {
01769         ++sl->c;
01770         return 0;
01771       }
01772     }
01773     else {
01774       if (!interlockedexchange(&sl->l, 1)) {
01775         assert(!sl->threadid);
01776         sl->c=CURRENT_THREAD;
01777         sl->threadid = CURRENT_THREAD;
01778         sl->c = 1;
01779         return 0;
01780       }
01781     }
01782     if ((++spins & SPINS_PER_YIELD) == 0)
01783       SleepEx(0, FALSE);
01784   }
01785 }
01786 
01787 static FORCEINLINE void win32_release_lock (MLOCK_T *sl) {
01788   assert(sl->threadid == CURRENT_THREAD);
01789   assert(sl->l != 0);
01790   if (--sl->c == 0) {
01791     sl->threadid = 0;
01792     interlockedexchange (&sl->l, 0);
01793   }
01794 }
01795 
01796 static FORCEINLINE int win32_try_lock (MLOCK_T *sl) {
01797   if(sl->l != 0) {
01798       if (sl->threadid == CURRENT_THREAD) {
01799         ++sl->c;
01800         return 1;
01801       }
01802   }
01803   else {
01804     if (!interlockedexchange(&sl->l, 1)){
01805       assert(!sl->threadid);
01806       sl->threadid = CURRENT_THREAD;
01807       sl->c = 1;
01808       return 1;
01809     }
01810   }
01811   return 0;
01812 }
01813 
01814 #endif /* WIN32 */
01815 #else /* USE_SPIN_LOCKS */
01816 
01817 #ifndef WIN32
01818 /* pthreads-based locks */
01819 
01820 #define MLOCK_T               pthread_mutex_t
01821 #define CURRENT_THREAD        pthread_self()
01822 #define INITIAL_LOCK(sl)      pthread_init_lock(sl)
01823 #define ACQUIRE_LOCK(sl)      pthread_mutex_lock(sl)
01824 #define RELEASE_LOCK(sl)      pthread_mutex_unlock(sl)
01825 #define TRY_LOCK(sl)          (!pthread_mutex_trylock(sl))
01826 
01827 static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;
01828 
01829 /* Cope with old-style linux recursive lock initialization by adding */
01830 /* skipped internal declaration from pthread.h */
01831 #ifdef linux
01832 #ifndef PTHREAD_MUTEX_RECURSIVE
01833 extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,
01834                        int __kind));
01835 #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
01836 #define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)
01837 #endif
01838 #endif
01839 
01840 static int pthread_init_lock (MLOCK_T *sl) {
01841   pthread_mutexattr_t attr;
01842   if (pthread_mutexattr_init(&attr)) return 1;
01843   if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;
01844   if (pthread_mutex_init(sl, &attr)) return 1;
01845   if (pthread_mutexattr_destroy(&attr)) return 1;
01846   return 0;
01847 }
01848 
01849 #else /* WIN32 */
01850 /* Win32 critical sections */
01851 #define MLOCK_T               CRITICAL_SECTION
01852 #define CURRENT_THREAD        GetCurrentThreadId()
01853 #define INITIAL_LOCK(s)       (!InitializeCriticalSectionAndSpinCount((s), 0x80000000|4000))
01854 #define ACQUIRE_LOCK(s)       (EnterCriticalSection(s), 0)
01855 #define RELEASE_LOCK(s)       LeaveCriticalSection(s)
01856 #define TRY_LOCK(s)           TryEnterCriticalSection(s)
01857 #define NEED_GLOBAL_LOCK_INIT
01858 
01859 static MLOCK_T malloc_global_mutex;
01860 static volatile long malloc_global_mutex_status;
01861 
01862 /* Use spin loop to initialize global lock */
01863 static void init_malloc_global_mutex() {
01864   for (;;) {
01865     long stat = malloc_global_mutex_status;
01866     if (stat > 0)
01867       return;
01868     /* transition to < 0 while initializing, then to > 0) */
01869     if (stat == 0 && 
01870         interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) {
01871       InitializeCriticalSection(&malloc_global_mutex);
01872       interlockedexchange(&malloc_global_mutex_status,1);
01873       return;
01874     }
01875     SleepEx(0, FALSE);
01876   }
01877 }
01878 
01879 #endif /* WIN32 */
01880 #endif /* USE_SPIN_LOCKS */
01881 #endif /* USE_LOCKS == 1 */
01882 
01883 /* -----------------------  User-defined locks ------------------------ */
01884 
01885 #if USE_LOCKS > 1
01886 /* Define your own lock implementation here */
01887 /* #define INITIAL_LOCK(sl)  ... */
01888 /* #define ACQUIRE_LOCK(sl)  ... */
01889 /* #define RELEASE_LOCK(sl)  ... */
01890 /* #define TRY_LOCK(sl) ... */
01891 /* static MLOCK_T malloc_global_mutex = ... */
01892 #endif /* USE_LOCKS > 1 */
01893 
01894 /* -----------------------  Lock-based state ------------------------ */
01895 
01896 #if USE_LOCKS
01897 #define USE_LOCK_BIT               (2U)
01898 #else  /* USE_LOCKS */
01899 #define USE_LOCK_BIT               (0U)
01900 #define INITIAL_LOCK(l)
01901 #endif /* USE_LOCKS */
01902 
01903 #if USE_LOCKS
01904 #define ACQUIRE_MALLOC_GLOBAL_LOCK()  ACQUIRE_LOCK(&malloc_global_mutex);
01905 #define RELEASE_MALLOC_GLOBAL_LOCK()  RELEASE_LOCK(&malloc_global_mutex);
01906 #else  /* USE_LOCKS */
01907 #define ACQUIRE_MALLOC_GLOBAL_LOCK()
01908 #define RELEASE_MALLOC_GLOBAL_LOCK()
01909 #endif /* USE_LOCKS */
01910 
01911 
01912 /* -----------------------  Chunk representations ------------------------ */
01913 
01914 /*
01915   (The following includes lightly edited explanations by Colin Plumb.)
01916 
01917   The malloc_chunk declaration below is misleading (but accurate and
01918   necessary).  It declares a "view" into memory allowing access to
01919   necessary fields at known offsets from a given base.
01920 
01921   Chunks of memory are maintained using a `boundary tag' method as
01922   originally described by Knuth.  (See the paper by Paul Wilson
01923   ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
01924   techniques.)  Sizes of free chunks are stored both in the front of
01925   each chunk and at the end.  This makes consolidating fragmented
01926   chunks into bigger chunks fast.  The head fields also hold bits
01927   representing whether chunks are free or in use.
01928 
01929   Here are some pictures to make it clearer.  They are "exploded" to
01930   show that the state of a chunk can be thought of as extending from
01931   the high 31 bits of the head field of its header through the
01932   prev_foot and PINUSE_BIT bit of the following chunk header.
01933 
01934   A chunk that's in use looks like:
01935 
01936    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01937            | Size of previous chunk (if P = 0)                             |
01938            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01939          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
01940          | Size of this chunk                                         1| +-+
01941    mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01942          |                                                               |
01943          +-                                                             -+
01944          |                                                               |
01945          +-                                                             -+
01946          |                                                               :
01947          +-      size - sizeof(size_t) available payload bytes          -+
01948          :                                                               |
01949  chunk-> +-                                                             -+
01950          |                                                               |
01951          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01952        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
01953        | Size of next chunk (may or may not be in use)               | +-+
01954  mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01955 
01956     And if it's free, it looks like this:
01957 
01958    chunk-> +-                                                             -+
01959            | User payload (must be in use, or we would have merged!)       |
01960            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01961          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
01962          | Size of this chunk                                         0| +-+
01963    mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01964          | Next pointer                                                  |
01965          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01966          | Prev pointer                                                  |
01967          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01968          |                                                               :
01969          +-      size - sizeof(struct chunk) unused bytes               -+
01970          :                                                               |
01971  chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01972          | Size of this chunk                                            |
01973          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01974        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
01975        | Size of next chunk (must be in use, or we would have merged)| +-+
01976  mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01977        |                                                               :
01978        +- User payload                                                -+
01979        :                                                               |
01980        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01981                                                                      |0|
01982                                                                      +-+
01983   Note that since we always merge adjacent free chunks, the chunks
01984   adjacent to a free chunk must be in use.
01985 
01986   Given a pointer to a chunk (which can be derived trivially from the
01987   payload pointer) we can, in O(1) time, find out whether the adjacent
01988   chunks are free, and if so, unlink them from the lists that they
01989   are on and merge them with the current chunk.
01990 
01991   Chunks always begin on even word boundaries, so the mem portion
01992   (which is returned to the user) is also on an even word boundary, and
01993   thus at least double-word aligned.
01994 
01995   The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
01996   chunk size (which is always a multiple of two words), is an in-use
01997   bit for the *previous* chunk.  If that bit is *clear*, then the
01998   word before the current chunk size contains the previous chunk
01999   size, and can be used to find the front of the previous chunk.
02000   The very first chunk allocated always has this bit set, preventing
02001   access to non-existent (or non-owned) memory. If pinuse is set for
02002   any given chunk, then you CANNOT determine the size of the
02003   previous chunk, and might even get a memory addressing fault when
02004   trying to do so.
02005 
02006   The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
02007   the chunk size redundantly records whether the current chunk is
02008   inuse. This redundancy enables usage checks within free and realloc,
02009   and reduces indirection when freeing and consolidating chunks.
02010 
02011   Each freshly allocated chunk must have both cinuse and pinuse set.
02012   That is, each allocated chunk borders either a previously allocated
02013   and still in-use chunk, or the base of its memory arena. This is
02014   ensured by making all allocations from the the `lowest' part of any
02015   found chunk.  Further, no free chunk physically borders another one,
02016   so each free chunk is known to be preceded and followed by either
02017   inuse chunks or the ends of memory.
02018 
02019   Note that the `foot' of the current chunk is actually represented
02020   as the prev_foot of the NEXT chunk. This makes it easier to
02021   deal with alignments etc but can be very confusing when trying
02022   to extend or adapt this code.
02023 
02024   The exceptions to all this are
02025 
02026      1. The special chunk `top' is the top-most available chunk (i.e.,
02027         the one bordering the end of available memory). It is treated
02028         specially.  Top is never included in any bin, is used only if
02029         no other chunk is available, and is released back to the
02030         system if it is very large (see M_TRIM_THRESHOLD).  In effect,
02031         the top chunk is treated as larger (and thus less well
02032         fitting) than any other available chunk.  The top chunk
02033         doesn't update its trailing size field since there is no next
02034         contiguous chunk that would have to index off it. However,
02035         space is still allocated for it (TOP_FOOT_SIZE) to enable
02036         separation or merging when space is extended.
02037 
02038      3. Chunks allocated via mmap, which have the lowest-order bit
02039         (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set
02040         PINUSE_BIT in their head fields.  Because they are allocated
02041         one-by-one, each must carry its own prev_foot field, which is
02042         also used to hold the offset this chunk has within its mmapped
02043         region, which is needed to preserve alignment. Each mmapped
02044         chunk is trailed by the first two fields of a fake next-chunk
02045         for sake of usage checks.
02046 
02047 */
02048 
02049 struct malloc_chunk {
02050   size_t               prev_foot;  /* Size of previous chunk (if free).  */
02051   size_t               head;       /* Size and inuse bits. */
02052   struct malloc_chunk* fd;         /* double links -- used only if free. */
02053   struct malloc_chunk* bk;
02054 };
02055 
02056 typedef struct malloc_chunk  mchunk;
02057 typedef struct malloc_chunk* mchunkptr;
02058 typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
02059 typedef unsigned int bindex_t;         /* Described below */
02060 typedef unsigned int binmap_t;         /* Described below */
02061 typedef unsigned int flag_t;           /* The type of various bit flag sets */
02062 
02063 /* ------------------- Chunks sizes and alignments ----------------------- */
02064 
02065 #define MCHUNK_SIZE         (sizeof(mchunk))
02066 
02067 #if FOOTERS
02068 #define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
02069 #else /* FOOTERS */
02070 #define CHUNK_OVERHEAD      (SIZE_T_SIZE)
02071 #endif /* FOOTERS */
02072 
02073 /* MMapped chunks need a second word of overhead ... */
02074 #define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
02075 /* ... and additional padding for fake next-chunk at foot */
02076 #define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
02077 
02078 /* The smallest size we can malloc is an aligned minimal chunk */
02079 #define MIN_CHUNK_SIZE\
02080   ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
02081 
02082 /* conversion from malloc headers to user pointers, and back */
02083 #define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
02084 #define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
02085 /* chunk associated with aligned address A */
02086 #define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
02087 
02088 /* Bounds on request (not chunk) sizes. */
02089 #define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
02090 #define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
02091 
02092 /* pad request bytes into a usable size */
02093 #define pad_request(req) \
02094    (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
02095 
02096 /* pad request, checking for minimum (but not maximum) */
02097 #define request2size(req) \
02098   (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
02099 
02100 
02101 /* ------------------ Operations on head and foot fields ----------------- */
02102 
02103 /*
02104   The head field of a chunk is or'ed with PINUSE_BIT when previous
02105   adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
02106   use. If the chunk was obtained with mmap, the prev_foot field has
02107   IS_MMAPPED_BIT set, otherwise holding the offset of the base of the
02108   mmapped region to the base of the chunk.
02109 
02110   FLAG4_BIT is not used by this malloc, but might be useful in extensions.
02111 */
02112 
02113 #define PINUSE_BIT          (SIZE_T_ONE)
02114 #define CINUSE_BIT          (SIZE_T_TWO)
02115 #define FLAG4_BIT           (SIZE_T_FOUR)
02116 #define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
02117 #define FLAG_BITS           (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)
02118 
02119 /* Head value for fenceposts */
02120 #define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
02121 
02122 /* extraction of fields from head words */
02123 #define cinuse(p)           ((p)->head & CINUSE_BIT)
02124 #define pinuse(p)           ((p)->head & PINUSE_BIT)
02125 #define chunksize(p)        ((p)->head & ~(FLAG_BITS))
02126 
02127 #define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
02128 #define clear_cinuse(p)     ((p)->head &= ~CINUSE_BIT)
02129 
02130 /* Treat space at ptr +/- offset as a chunk */
02131 #define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
02132 #define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
02133 
02134 /* Ptr to next or previous physical malloc_chunk. */
02135 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))
02136 #define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
02137 
02138 /* extract next chunk's pinuse bit */
02139 #define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
02140 
02141 /* Get/set size at footer */
02142 #define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
02143 #define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
02144 
02145 /* Set size, pinuse bit, and foot */
02146 #define set_size_and_pinuse_of_free_chunk(p, s)\
02147   ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
02148 
02149 /* Set size, pinuse bit, foot, and clear next pinuse */
02150 #define set_free_with_pinuse(p, s, n)\
02151   (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
02152 
02153 #define is_mmapped(p)\
02154   (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))
02155 
02156 /* Get the internal overhead associated with chunk p */
02157 #define overhead_for(p)\
02158  (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
02159 
02160 /* Return true if malloced space is not necessarily cleared */
02161 #if MMAP_CLEARS
02162 #define calloc_must_clear(p) (!is_mmapped(p))
02163 #else /* MMAP_CLEARS */
02164 #define calloc_must_clear(p) (1)
02165 #endif /* MMAP_CLEARS */
02166 
02167 /* ---------------------- Overlaid data structures ----------------------- */
02168 
02169 /*
02170   When chunks are not in use, they are treated as nodes of either
02171   lists or trees.
02172 
02173   "Small"  chunks are stored in circular doubly-linked lists, and look
02174   like this:
02175 
02176     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02177             |             Size of previous chunk                            |
02178             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02179     `head:' |             Size of chunk, in bytes                         |P|
02180       mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02181             |             Forward pointer to next chunk in list             |
02182             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02183             |             Back pointer to previous chunk in list            |
02184             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02185             |             Unused space (may be 0 bytes long)                .
02186             .                                                               .
02187             .                                                               |
02188 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02189     `foot:' |             Size of chunk, in bytes                           |
02190             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02191 
02192   Larger chunks are kept in a form of bitwise digital trees (aka
02193   tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
02194   free chunks greater than 256 bytes, their size doesn't impose any
02195   constraints on user chunk sizes.  Each node looks like:
02196 
02197     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02198             |             Size of previous chunk                            |
02199             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02200     `head:' |             Size of chunk, in bytes                         |P|
02201       mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02202             |             Forward pointer to next chunk of same size        |
02203             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02204             |             Back pointer to previous chunk of same size       |
02205             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02206             |             Pointer to left child (child[0])                  |
02207             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02208             |             Pointer to right child (child[1])                 |
02209             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02210             |             Pointer to parent                                 |
02211             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02212             |             bin index of this chunk                           |
02213             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02214             |             Unused space                                      .
02215             .                                                               |
02216 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02217     `foot:' |             Size of chunk, in bytes                           |
02218             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
02219 
02220   Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
02221   of the same size are arranged in a circularly-linked list, with only
02222   the oldest chunk (the next to be used, in our FIFO ordering)
02223   actually in the tree.  (Tree members are distinguished by a non-null
02224   parent pointer.)  If a chunk with the same size an an existing node
02225   is inserted, it is linked off the existing node using pointers that
02226   work in the same way as fd/bk pointers of small chunks.
02227 
02228   Each tree contains a power of 2 sized range of chunk sizes (the
02229   smallest is 0x100 <= x < 0x180), which is is divided in half at each
02230   tree level, with the chunks in the smaller half of the range (0x100
02231   <= x < 0x140 for the top nose) in the left subtree and the larger
02232   half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
02233   done by inspecting individual bits.
02234 
02235   Using these rules, each node's left subtree contains all smaller
02236   sizes than its right subtree.  However, the node at the root of each
02237   subtree has no particular ordering relationship to either.  (The
02238   dividing line between the subtree sizes is based on trie relation.)
02239   If we remove the last chunk of a given size from the interior of the
02240   tree, we need to replace it with a leaf node.  The tree ordering
02241   rules permit a node to be replaced by any leaf below it.
02242 
02243   The smallest chunk in a tree (a common operation in a best-fit
02244   allocator) can be found by walking a path to the leftmost leaf in
02245   the tree.  Unlike a usual binary tree, where we follow left child
02246   pointers until we reach a null, here we follow the right child
02247   pointer any time the left one is null, until we reach a leaf with
02248   both child pointers null. The smallest chunk in the tree will be
02249   somewhere along that path.
02250 
02251   The worst case number of steps to add, find, or remove a node is
02252   bounded by the number of bits differentiating chunks within
02253   bins. Under current bin calculations, this ranges from 6 up to 21
02254   (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
02255   is of course much better.
02256 */
02257 
02258 struct malloc_tree_chunk {
02259   /* The first four fields must be compatible with malloc_chunk */
02260   size_t                    prev_foot;
02261   size_t                    head;
02262   struct malloc_tree_chunk* fd;
02263   struct malloc_tree_chunk* bk;
02264 
02265   struct malloc_tree_chunk* child[2];
02266   struct malloc_tree_chunk* parent;
02267   bindex_t                  index;
02268 };
02269 
02270 typedef struct malloc_tree_chunk  tchunk;
02271 typedef struct malloc_tree_chunk* tchunkptr;
02272 typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
02273 
02274 /* A little helper macro for trees */
02275 #define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
02276 
02277 /* ----------------------------- Segments -------------------------------- */
02278 
02279 /*
02280   Each malloc space may include non-contiguous segments, held in a
02281   list headed by an embedded malloc_segment record representing the
02282   top-most space. Segments also include flags holding properties of
02283   the space. Large chunks that are directly allocated by mmap are not
02284   included in this list. They are instead independently created and
02285   destroyed without otherwise keeping track of them.
02286 
02287   Segment management mainly comes into play for spaces allocated by
02288   MMAP.  Any call to MMAP might or might not return memory that is
02289   adjacent to an existing segment.  MORECORE normally contiguously
02290   extends the current space, so this space is almost always adjacent,
02291   which is simpler and faster to deal with. (This is why MORECORE is
02292   used preferentially to MMAP when both are available -- see
02293   sys_alloc.)  When allocating using MMAP, we don't use any of the
02294   hinting mechanisms (inconsistently) supported in various
02295   implementations of unix mmap, or distinguish reserving from
02296   committing memory. Instead, we just ask for space, and exploit
02297   contiguity when we get it.  It is probably possible to do
02298   better than this on some systems, but no general scheme seems
02299   to be significantly better.
02300 
02301   Management entails a simpler variant of the consolidation scheme
02302   used for chunks to reduce fragmentation -- new adjacent memory is
02303   normally prepended or appended to an existing segment. However,
02304   there are limitations compared to chunk consolidation that mostly
02305   reflect the fact that segment processing is relatively infrequent
02306   (occurring only when getting memory from system) and that we
02307   don't expect to have huge numbers of segments:
02308 
02309   * Segments are not indexed, so traversal requires linear scans.  (It
02310     would be possible to index these, but is not worth the extra
02311     overhead and complexity for most programs on most platforms.)
02312   * New segments are only appended to old ones when holding top-most
02313     memory; if they cannot be prepended to others, they are held in
02314     different segments.
02315 
02316   Except for the top-most segment of an mstate, each segment record
02317   is kept at the tail of its segment. Segments are added by pushing
02318   segment records onto the list headed by &mstate.seg for the
02319   containing mstate.
02320 
02321   Segment flags control allocation/merge/deallocation policies:
02322   * If EXTERN_BIT set, then we did not allocate this segment,
02323     and so should not try to deallocate or merge with others.
02324     (This currently holds only for the initial segment passed
02325     into create_mspace_with_base.)
02326   * If IS_MMAPPED_BIT set, the segment may be merged with
02327     other surrounding mmapped segments and trimmed/de-allocated
02328     using munmap.
02329   * If neither bit is set, then the segment was obtained using
02330     MORECORE so can be merged with surrounding MORECORE'd segments
02331     and deallocated/trimmed using MORECORE with negative arguments.
02332 */
02333 
02334 struct malloc_segment {
02335   char*        base;             /* base address */
02336   size_t       size;             /* allocated size */
02337   struct malloc_segment* next;   /* ptr to next segment */
02338   flag_t       sflags;           /* mmap and extern flag */
02339 };
02340 
02341 #define is_mmapped_segment(S)  ((S)->sflags & IS_MMAPPED_BIT)
02342 #define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)
02343 
02344 typedef struct malloc_segment  msegment;
02345 typedef struct malloc_segment* msegmentptr;
02346 
02347 /* ---------------------------- malloc_state ----------------------------- */
02348 
02349 /*
02350    A malloc_state holds all of the bookkeeping for a space.
02351    The main fields are:
02352 
02353   Top
02354     The topmost chunk of the currently active segment. Its size is
02355     cached in topsize.  The actual size of topmost space is
02356     topsize+TOP_FOOT_SIZE, which includes space reserved for adding
02357     fenceposts and segment records if necessary when getting more
02358     space from the system.  The size at which to autotrim top is
02359     cached from mparams in trim_check, except that it is disabled if
02360     an autotrim fails.
02361 
02362   Designated victim (dv)
02363     This is the preferred chunk for servicing small requests that
02364     don't have exact fits.  It is normally the chunk split off most
02365     recently to service another small request.  Its size is cached in
02366     dvsize. The link fields of this chunk are not maintained since it
02367     is not kept in a bin.
02368 
02369   SmallBins
02370     An array of bin headers for free chunks.  These bins hold chunks
02371     with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
02372     chunks of all the same size, spaced 8 bytes apart.  To simplify
02373     use in double-linked lists, each bin header acts as a malloc_chunk
02374     pointing to the real first node, if it exists (else pointing to
02375     itself).  This avoids special-casing for headers.  But to avoid
02376     waste, we allocate only the fd/bk pointers of bins, and then use
02377     repositioning tricks to treat these as the fields of a chunk.
02378 
02379   TreeBins
02380     Treebins are pointers to the roots of trees holding a range of
02381     sizes. There are 2 equally spaced treebins for each power of two
02382     from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
02383     larger.
02384 
02385   Bin maps
02386     There is one bit map for small bins ("smallmap") and one for
02387     treebins ("treemap).  Each bin sets its bit when non-empty, and
02388     clears the bit when empty.  Bit operations are then used to avoid
02389     bin-by-bin searching -- nearly all "search" is done without ever
02390     looking at bins that won't be selected.  The bit maps
02391     conservatively use 32 bits per map word, even if on 64bit system.
02392     For a good description of some of the bit-based techniques used
02393     here, see Henry S. Warren Jr's book "Hacker's Delight" (and
02394     supplement at http://hackersdelight.org/). Many of these are
02395     intended to reduce the branchiness of paths through malloc etc, as
02396     well as to reduce the number of memory locations read or written.
02397 
02398   Segments
02399     A list of segments headed by an embedded malloc_segment record
02400     representing the initial space.
02401 
02402   Address check support
02403     The least_addr field is the least address ever obtained from
02404     MORECORE or MMAP. Attempted frees and reallocs of any address less
02405     than this are trapped (unless INSECURE is defined).
02406 
02407   Magic tag
02408     A cross-check field that should always hold same value as mparams.magic.
02409 
02410   Flags
02411     Bits recording whether to use MMAP, locks, or contiguous MORECORE
02412 
02413   Statistics
02414     Each space keeps track of current and maximum system memory
02415     obtained via MORECORE or MMAP.
02416 
02417   Trim support
02418     Fields holding the amount of unused topmost memory that should trigger
02419     timming, and a counter to force periodic scanning to release unused
02420     non-topmost segments.
02421 
02422   Locking
02423     If USE_LOCKS is defined, the "mutex" lock is acquired and released
02424     around every public call using this mspace.
02425 
02426   Extension support
02427     A void* pointer and a size_t field that can be used to help implement
02428     extensions to this malloc.
02429 */
02430 
02431 /* Bin types, widths and sizes */
02432 #define NSMALLBINS        (32U)
02433 #define NTREEBINS         (32U)
02434 #define SMALLBIN_SHIFT    (3U)
02435 #define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
02436 #define TREEBIN_SHIFT     (8U)
02437 #define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
02438 #define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
02439 #define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
02440 
02441 struct malloc_state {
02442   binmap_t   smallmap;
02443   binmap_t   treemap;
02444   size_t     dvsize;
02445   size_t     topsize;
02446   char*      least_addr;
02447   mchunkptr  dv;
02448   mchunkptr  top;
02449   size_t     trim_check;
02450   size_t     release_checks;
02451   size_t     magic;
02452   mchunkptr  smallbins[(NSMALLBINS+1)*2];
02453   tbinptr    treebins[NTREEBINS];
02454   size_t     footprint;
02455   size_t     max_footprint;
02456   flag_t     mflags;
02457 #if USE_LOCKS
02458   MLOCK_T    mutex;     /* locate lock among fields that rarely change */
02459 #endif /* USE_LOCKS */
02460   msegment   seg;
02461   void*      extp;      /* Unused but available for extensions */
02462   size_t     exts;
02463 };
02464 
02465 typedef struct malloc_state*    mstate;
02466 
02467 /* ------------- Global malloc_state and malloc_params ------------------- */
02468 
02469 /*
02470   malloc_params holds global properties, including those that can be
02471   dynamically set using mallopt. There is a single instance, mparams,
02472   initialized in init_mparams. Note that the non-zeroness of "magic"
02473   also serves as an initialization flag.
02474 */
02475 
02476 struct malloc_params {
02477   volatile size_t magic;
02478   size_t page_size;
02479   size_t granularity;
02480   size_t mmap_threshold;
02481   size_t trim_threshold;
02482   flag_t default_mflags;
02483 };
02484 
02485 static struct malloc_params mparams;
02486 
02487 /* Ensure mparams initialized */
02488 #define ensure_initialization() (mparams.magic != 0 || init_mparams())
02489 
02490 #if !ONLY_MSPACES
02491 
02492 /* The global malloc_state used for all non-"mspace" calls */
02493 static struct malloc_state _gm_;
02494 #define gm                 (&_gm_)
02495 #define is_global(M)       ((M) == &_gm_)
02496 
02497 #endif /* !ONLY_MSPACES */
02498 
02499 #define is_initialized(M)  ((M)->top != 0)
02500 
02501 /* -------------------------- system alloc setup ------------------------- */
02502 
02503 /* Operations on mflags */
02504 
02505 #define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
02506 #define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
02507 #define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
02508 
02509 #define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
02510 #define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
02511 #define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
02512 
02513 #define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
02514 #define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
02515 
02516 #define set_lock(M,L)\
02517  ((M)->mflags = (L)?\
02518   ((M)->mflags | USE_LOCK_BIT) :\
02519   ((M)->mflags & ~USE_LOCK_BIT))
02520 
02521 /* page-align a size */
02522 #define page_align(S)\
02523  (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))
02524 
02525 /* granularity-align a size */
02526 #define granularity_align(S)\
02527   (((S) + (mparams.granularity - SIZE_T_ONE))\
02528    & ~(mparams.granularity - SIZE_T_ONE))
02529 
02530 
02531 /* For mmap, use granularity alignment on windows, else page-align */
02532 #ifdef WIN32
02533 #define mmap_align(S) granularity_align(S)
02534 #else
02535 #define mmap_align(S) page_align(S)
02536 #endif
02537 
02538 /* For sys_alloc, enough padding to ensure can malloc request on success */
02539 #define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)
02540 
02541 #define is_page_aligned(S)\
02542    (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
02543 #define is_granularity_aligned(S)\
02544    (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
02545 
02546 /*  True if segment S holds address A */
02547 #define segment_holds(S, A)\
02548   ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
02549 
02550 /* Return segment holding given address */
02551 static msegmentptr segment_holding(mstate m, char* addr) {
02552   msegmentptr sp = &m->seg;
02553   for (;;) {
02554     if (addr >= sp->base && addr < sp->base + sp->size)
02555       return sp;
02556     if ((sp = sp->next) == 0)
02557       return 0;
02558   }
02559 }
02560 
02561 /* Return true if segment contains a segment link */
02562 static int has_segment_link(mstate m, msegmentptr ss) {
02563   msegmentptr sp = &m->seg;
02564   for (;;) {
02565     if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
02566       return 1;
02567     if ((sp = sp->next) == 0)
02568       return 0;
02569   }
02570 }
02571 
02572 #ifndef MORECORE_CANNOT_TRIM
02573 #define should_trim(M,s)  ((s) > (M)->trim_check)
02574 #else  /* MORECORE_CANNOT_TRIM */
02575 #define should_trim(M,s)  (0)
02576 #endif /* MORECORE_CANNOT_TRIM */
02577 
02578 /*
02579   TOP_FOOT_SIZE is padding at the end of a segment, including space
02580   that may be needed to place segment records and fenceposts when new
02581   noncontiguous segments are added.
02582 */
02583 #define TOP_FOOT_SIZE\
02584   (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
02585 
02586 
02587 /* -------------------------------  Hooks -------------------------------- */
02588 
02589 /*
02590   PREACTION should be defined to return 0 on success, and nonzero on
02591   failure. If you are not using locking, you can redefine these to do
02592   anything you like.
02593 */
02594 
02595 #if USE_LOCKS
02596 
02597 #define PREACTION(M)  ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
02598 #define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
02599 #else /* USE_LOCKS */
02600 
02601 #ifndef PREACTION
02602 #define PREACTION(M) (0)
02603 #endif  /* PREACTION */
02604 
02605 #ifndef POSTACTION
02606 #define POSTACTION(M)
02607 #endif  /* POSTACTION */
02608 
02609 #endif /* USE_LOCKS */
02610 
02611 /*
02612   CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
02613   USAGE_ERROR_ACTION is triggered on detected bad frees and
02614   reallocs. The argument p is an address that might have triggered the
02615   fault. It is ignored by the two predefined actions, but might be
02616   useful in custom actions that try to help diagnose errors.
02617 */
02618 
02619 #if PROCEED_ON_ERROR
02620 
02621 /* A count of the number of corruption errors causing resets */
02622 int malloc_corruption_error_count;
02623 
02624 /* default corruption action */
02625 static void reset_on_error(mstate m);
02626 
02627 #define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
02628 #define USAGE_ERROR_ACTION(m, p)
02629 
02630 #else /* PROCEED_ON_ERROR */
02631 
02632 #ifndef CORRUPTION_ERROR_ACTION
02633 #define CORRUPTION_ERROR_ACTION(m) ABORT
02634 #endif /* CORRUPTION_ERROR_ACTION */
02635 
02636 #ifndef USAGE_ERROR_ACTION
02637 #define USAGE_ERROR_ACTION(m,p) ABORT
02638 #endif /* USAGE_ERROR_ACTION */
02639 
02640 #endif /* PROCEED_ON_ERROR */
02641 
02642 /* -------------------------- Debugging setup ---------------------------- */
02643 
02644 #if ! DEBUG
02645 
02646 #define check_free_chunk(M,P)
02647 #define check_inuse_chunk(M,P)
02648 #define check_malloced_chunk(M,P,N)
02649 #define check_mmapped_chunk(M,P)
02650 #define check_malloc_state(M)
02651 #define check_top_chunk(M,P)
02652 
02653 #else /* DEBUG */
02654 #define check_free_chunk(M,P)       do_check_free_chunk(M,P)
02655 #define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
02656 #define check_top_chunk(M,P)        do_check_top_chunk(M,P)
02657 #define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
02658 #define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
02659 #define check_malloc_state(M)       do_check_malloc_state(M)
02660 
02661 static void   do_check_any_chunk(mstate m, mchunkptr p);
02662 static void   do_check_top_chunk(mstate m, mchunkptr p);
02663 static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
02664 static void   do_check_inuse_chunk(mstate m, mchunkptr p);
02665 static void   do_check_free_chunk(mstate m, mchunkptr p);
02666 static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
02667 static void   do_check_tree(mstate m, tchunkptr t);
02668 static void   do_check_treebin(mstate m, bindex_t i);
02669 static void   do_check_smallbin(mstate m, bindex_t i);
02670 static void   do_check_malloc_state(mstate m);
02671 static int    bin_find(mstate m, mchunkptr x);
02672 static size_t traverse_and_check(mstate m);
02673 #endif /* DEBUG */
02674 
02675 /* ---------------------------- Indexing Bins ---------------------------- */
02676 
02677 #define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
02678 #define small_index(s)      ((s)  >> SMALLBIN_SHIFT)
02679 #define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
02680 #define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
02681 
02682 /* addressing by index. See above about smallbin repositioning */
02683 #define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
02684 #define treebin_at(M,i)     (&((M)->treebins[i]))
02685 
02686 /* assign tree index for size S to variable I. Use x86 asm if possible  */
02687 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
02688 #define compute_tree_index(S, I)\
02689 {\
02690   unsigned int X = S >> TREEBIN_SHIFT;\
02691   if (X == 0)\
02692     I = 0;\
02693   else if (X > 0xFFFF)\
02694     I = NTREEBINS-1;\
02695   else {\
02696     unsigned int K;\
02697     __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "rm"  (X));\
02698     I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
02699   }\
02700 }
02701 
02702 #elif defined (__INTEL_COMPILER)
02703 #define compute_tree_index(S, I)\
02704 {\
02705   size_t X = S >> TREEBIN_SHIFT;\
02706   if (X == 0)\
02707     I = 0;\
02708   else if (X > 0xFFFF)\
02709     I = NTREEBINS-1;\
02710   else {\
02711     unsigned int K = _bit_scan_reverse (X); \
02712     I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
02713   }\
02714 }
02715 
02716 #elif defined(_MSC_VER) && _MSC_VER>=1300
02717 #define compute_tree_index(S, I)\
02718 {\
02719   size_t X = S >> TREEBIN_SHIFT;\
02720   if (X == 0)\
02721     I = 0;\
02722   else if (X > 0xFFFF)\
02723     I = NTREEBINS-1;\
02724   else {\
02725     unsigned int K;\
02726     _BitScanReverse((DWORD *) &K, X);\
02727     I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
02728   }\
02729 }
02730 
02731 #else /* GNUC */
02732 #define compute_tree_index(S, I)\
02733 {\
02734   size_t X = S >> TREEBIN_SHIFT;\
02735   if (X == 0)\
02736     I = 0;\
02737   else if (X > 0xFFFF)\
02738     I = NTREEBINS-1;\
02739   else {\
02740     unsigned int Y = (unsigned int)X;\
02741     unsigned int N = ((Y - 0x100) >> 16) & 8;\
02742     unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
02743     N += K;\
02744     N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
02745     K = 14 - N + ((Y <<= K) >> 15);\
02746     I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
02747   }\
02748 }
02749 #endif /* GNUC */
02750 
02751 /* Bit representing maximum resolved size in a treebin at i */
02752 #define bit_for_tree_index(i) \
02753    (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
02754 
02755 /* Shift placing maximum resolved bit in a treebin at i as sign bit */
02756 #define leftshift_for_tree_index(i) \
02757    ((i == NTREEBINS-1)? 0 : \
02758     ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
02759 
02760 /* The size of the smallest chunk held in bin with index i */
02761 #define minsize_for_tree_index(i) \
02762    ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
02763    (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
02764 
02765 
02766 /* ------------------------ Operations on bin maps ----------------------- */
02767 
02768 /* bit corresponding to given index */
02769 #define idx2bit(i)              ((binmap_t)(1) << (i))
02770 
02771 /* Mark/Clear bits with given index */
02772 #define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
02773 #define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
02774 #define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
02775 
02776 #define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
02777 #define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
02778 #define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
02779 
02780 /* isolate the least set bit of a bitmap */
02781 #define least_bit(x)         ((x) & -(x))
02782 
02783 /* mask with all bits to left of least bit of x on */
02784 #define left_bits(x)         ((x<<1) | -(x<<1))
02785 
02786 /* mask with all bits to left of or equal to least bit of x on */
02787 #define same_or_left_bits(x) ((x) | -(x))
02788 
02789 /* index corresponding to given bit. Use x86 asm if possible */
02790 
02791 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
02792 #define compute_bit2idx(X, I)\
02793 {\
02794   unsigned int J;\
02795   __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "rm" (X));\
02796   I = (bindex_t)J;\
02797 }
02798 
02799 #elif defined (__INTEL_COMPILER)
02800 #define compute_bit2idx(X, I)\
02801 {\
02802   unsigned int J;\
02803   J = _bit_scan_forward (X); \
02804   I = (bindex_t)J;\
02805 }
02806 
02807 #elif defined(_MSC_VER) && _MSC_VER>=1300
02808 #define compute_bit2idx(X, I)\
02809 {\
02810   unsigned int J;\
02811   _BitScanForward((DWORD *) &J, X);\
02812   I = (bindex_t)J;\
02813 }
02814 
02815 #elif USE_BUILTIN_FFS
02816 #define compute_bit2idx(X, I) I = ffs(X)-1
02817 
02818 #else 
02819 #define compute_bit2idx(X, I)\
02820 {\
02821   unsigned int Y = X - 1;\
02822   unsigned int K = Y >> (16-4) & 16;\
02823   unsigned int N = K;        Y >>= K;\
02824   N += K = Y >> (8-3) &  8;  Y >>= K;\
02825   N += K = Y >> (4-2) &  4;  Y >>= K;\
02826   N += K = Y >> (2-1) &  2;  Y >>= K;\
02827   N += K = Y >> (1-0) &  1;  Y >>= K;\
02828   I = (bindex_t)(N + Y);\
02829 }
02830 #endif /* GNUC */
02831 
02832 
02833 /* ----------------------- Runtime Check Support ------------------------- */
02834 
02835 /*
02836   For security, the main invariant is that malloc/free/etc never
02837   writes to a static address other than malloc_state, unless static
02838   malloc_state itself has been corrupted, which cannot occur via
02839   malloc (because of these checks). In essence this means that we
02840   believe all pointers, sizes, maps etc held in malloc_state, but
02841   check all of those linked or offsetted from other embedded data
02842   structures.  These checks are interspersed with main code in a way
02843   that tends to minimize their run-time cost.
02844 
02845   When FOOTERS is defined, in addition to range checking, we also
02846   verify footer fields of inuse chunks, which can be used guarantee
02847   that the mstate controlling malloc/free is intact.  This is a
02848   streamlined version of the approach described by William Robertson
02849   et al in "Run-time Detection of Heap-based Overflows" LISA'03
02850   http://www.usenix.org/events/lisa03/tech/robertson.html The footer
02851   of an inuse chunk holds the xor of its mstate and a random seed,
02852   that is checked upon calls to free() and realloc().  This is
02853   (probablistically) unguessable from outside the program, but can be
02854   computed by any code successfully malloc'ing any chunk, so does not
02855   itself provide protection against code that has already broken
02856   security through some other means.  Unlike Robertson et al, we
02857   always dynamically check addresses of all offset chunks (previous,
02858   next, etc). This turns out to be cheaper than relying on hashes.
02859 */
02860 
02861 #if !INSECURE
02862 /* Check if address a is at least as high as any from MORECORE or MMAP */
02863 #define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
02864 /* Check if address of next chunk n is higher than base chunk p */
02865 #define ok_next(p, n)    ((char*)(p) < (char*)(n))
02866 /* Check if p has its cinuse bit on */
02867 #define ok_cinuse(p)     cinuse(p)
02868 /* Check if p has its pinuse bit on */
02869 #define ok_pinuse(p)     pinuse(p)
02870 
02871 #else /* !INSECURE */
02872 #define ok_address(M, a) (1)
02873 #define ok_next(b, n)    (1)
02874 #define ok_cinuse(p)     (1)
02875 #define ok_pinuse(p)     (1)
02876 #endif /* !INSECURE */
02877 
02878 #if (FOOTERS && !INSECURE)
02879 /* Check if (alleged) mstate m has expected magic field */
02880 #define ok_magic(M)      ((M)->magic == mparams.magic)
02881 #else  /* (FOOTERS && !INSECURE) */
02882 #define ok_magic(M)      (1)
02883 #endif /* (FOOTERS && !INSECURE) */
02884 
02885 
02886 /* In gcc, use __builtin_expect to minimize impact of checks */
02887 #if !INSECURE
02888 #if defined(__GNUC__) && __GNUC__ >= 3
02889 #define RTCHECK(e)  __builtin_expect(e, 1)
02890 #else /* GNUC */
02891 #define RTCHECK(e)  (e)
02892 #endif /* GNUC */
02893 #else /* !INSECURE */
02894 #define RTCHECK(e)  (1)
02895 #endif /* !INSECURE */
02896 
02897 /* macros to set up inuse chunks with or without footers */
02898 
02899 #if !FOOTERS
02900 
02901 #define mark_inuse_foot(M,p,s)
02902 
02903 /* Set cinuse bit and pinuse bit of next chunk */
02904 #define set_inuse(M,p,s)\
02905   ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
02906   ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
02907 
02908 /* Set cinuse and pinuse of this chunk and pinuse of next chunk */
02909 #define set_inuse_and_pinuse(M,p,s)\
02910   ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
02911   ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
02912 
02913 /* Set size, cinuse and pinuse bit of this chunk */
02914 #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
02915   ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
02916 
02917 #else /* FOOTERS */
02918 
02919 /* Set foot of inuse chunk to be xor of mstate and seed */
02920 #define mark_inuse_foot(M,p,s)\
02921   (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
02922 
02923 #define get_mstate_for(p)\
02924   ((mstate)(((mchunkptr)((char*)(p) +\
02925     (chunksize(p))))->prev_foot ^ mparams.magic))
02926 
02927 #define set_inuse(M,p,s)\
02928   ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
02929   (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
02930   mark_inuse_foot(M,p,s))
02931 
02932 #define set_inuse_and_pinuse(M,p,s)\
02933   ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
02934   (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
02935  mark_inuse_foot(M,p,s))
02936 
02937 #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
02938   ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
02939   mark_inuse_foot(M, p, s))
02940 
02941 #endif /* !FOOTERS */
02942 
02943 /* ---------------------------- setting mparams -------------------------- */
02944 
02945 /* Initialize mparams */
02946 static int init_mparams(void) {
02947 #ifdef NEED_GLOBAL_LOCK_INIT
02948   if (malloc_global_mutex_status <= 0)
02949     init_malloc_global_mutex();
02950 #endif
02951 
02952   ACQUIRE_MALLOC_GLOBAL_LOCK();
02953   if (mparams.magic == 0) {
02954     size_t magic;
02955     size_t psize;
02956     size_t gsize;
02957    
02958 #ifndef WIN32
02959     psize = malloc_getpagesize;
02960     gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);
02961 #else /* WIN32 */
02962     {
02963       SYSTEM_INFO system_info;
02964       GetSystemInfo(&system_info);
02965       psize = system_info.dwPageSize;
02966       gsize = ((DEFAULT_GRANULARITY != 0)?
02967                DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);
02968     }
02969 #endif /* WIN32 */
02970 
02971     /* Sanity-check configuration:
02972        size_t must be unsigned and as wide as pointer type.
02973        ints must be at least 4 bytes.
02974        alignment must be at least 8.
02975        Alignment, min chunk size, and page size must all be powers of 2.
02976     */
02977     if ((sizeof(size_t) != sizeof(char*)) ||
02978         (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
02979         (sizeof(int) < 4)  ||
02980         (MALLOC_ALIGNMENT < (size_t)8U) ||
02981         ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||
02982         ((MCHUNK_SIZE      & (MCHUNK_SIZE-SIZE_T_ONE))      != 0) ||
02983         ((gsize            & (gsize-SIZE_T_ONE))            != 0) ||
02984         ((psize            & (psize-SIZE_T_ONE))            != 0))
02985       ABORT;
02986 
02987     mparams.granularity = gsize;
02988     mparams.page_size = psize;
02989     mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
02990     mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
02991 #if MORECORE_CONTIGUOUS
02992     mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
02993 #else  /* MORECORE_CONTIGUOUS */
02994     mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
02995 #endif /* MORECORE_CONTIGUOUS */
02996 
02997 #if !ONLY_MSPACES
02998     /* Set up lock for main malloc area */
02999     gm->mflags = mparams.default_mflags;
03000     INITIAL_LOCK(&gm->mutex);
03001 #endif
03002 
03003 #if (FOOTERS && !INSECURE)
03004     {
03005 #if USE_DEV_RANDOM
03006       int fd;
03007       unsigned char buf[sizeof(size_t)];
03008       /* Try to use /dev/urandom, else fall back on using time */
03009       if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
03010           read(fd, buf, sizeof(buf)) == sizeof(buf)) {
03011         magic = *((size_t *) buf);
03012         close(fd);
03013       }
03014       else 
03015 #endif /* USE_DEV_RANDOM */
03016 #ifdef WIN32
03017         magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);
03018 #else
03019       magic = (size_t)(time(0) ^ (size_t)0x55555555U);
03020 #endif
03021       magic |= (size_t)8U;    /* ensure nonzero */
03022       magic &= ~(size_t)7U;   /* improve chances of fault for bad values */
03023     }
03024 #else /* (FOOTERS && !INSECURE) */
03025     magic = (size_t)0x58585858U;
03026 #endif /* (FOOTERS && !INSECURE) */
03027 
03028     mparams.magic = magic;
03029   }
03030 
03031   RELEASE_MALLOC_GLOBAL_LOCK();
03032   return 1;
03033 }
03034 
03035 /* support for mallopt */
03036 static int change_mparam(int param_number, int value) {
03037   size_t val = (value == -1)? MAX_SIZE_T : (size_t)value;
03038   ensure_initialization();
03039   switch(param_number) {
03040   case M_TRIM_THRESHOLD:
03041     mparams.trim_threshold = val;
03042     return 1;
03043   case M_GRANULARITY:
03044     if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
03045       mparams.granularity = val;
03046       return 1;
03047     }
03048     else
03049       return 0;
03050   case M_MMAP_THRESHOLD:
03051     mparams.mmap_threshold = val;
03052     return 1;
03053   default:
03054     return 0;
03055   }
03056 }
03057 
03058 #if DEBUG
03059 /* ------------------------- Debugging Support --------------------------- */
03060 
03061 /* Check properties of any chunk, whether free, inuse, mmapped etc  */
03062 static void do_check_any_chunk(mstate m, mchunkptr p) {
03063   assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
03064   assert(ok_address(m, p));
03065 }
03066 
03067 /* Check properties of top chunk */
03068 static void do_check_top_chunk(mstate m, mchunkptr p) {
03069   msegmentptr sp = segment_holding(m, (char*)p);
03070   size_t  sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */
03071   assert(sp != 0);
03072   assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
03073   assert(ok_address(m, p));
03074   assert(sz == m->topsize);
03075   assert(sz > 0);
03076   assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
03077   assert(pinuse(p));
03078   assert(!pinuse(chunk_plus_offset(p, sz)));
03079 }
03080 
03081 /* Check properties of (inuse) mmapped chunks */
03082 static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
03083   size_t  sz = chunksize(p);
03084   size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD);
03085   assert(is_mmapped(p));
03086   assert(use_mmap(m));
03087   assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
03088   assert(ok_address(m, p));
03089   assert(!is_small(sz));
03090   assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
03091   assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
03092   assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
03093 }
03094 
03095 /* Check properties of inuse chunks */
03096 static void do_check_inuse_chunk(mstate m, mchunkptr p) {
03097   do_check_any_chunk(m, p);
03098   assert(cinuse(p));
03099   assert(next_pinuse(p));
03100   /* If not pinuse and not mmapped, previous chunk has OK offset */
03101   assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
03102   if (is_mmapped(p))
03103     do_check_mmapped_chunk(m, p);
03104 }
03105 
03106 /* Check properties of free chunks */
03107 static void do_check_free_chunk(mstate m, mchunkptr p) {
03108   size_t sz = chunksize(p);
03109   mchunkptr next = chunk_plus_offset(p, sz);
03110   do_check_any_chunk(m, p);
03111   assert(!cinuse(p));
03112   assert(!next_pinuse(p));
03113   assert (!is_mmapped(p));
03114   if (p != m->dv && p != m->top) {
03115     if (sz >= MIN_CHUNK_SIZE) {
03116       assert((sz & CHUNK_ALIGN_MASK) == 0);
03117       assert(is_aligned(chunk2mem(p)));
03118       assert(next->prev_foot == sz);
03119       assert(pinuse(p));
03120       assert (next == m->top || cinuse(next));
03121       assert(p->fd->bk == p);
03122       assert(p->bk->fd == p);
03123     }
03124     else  /* markers are always of size SIZE_T_SIZE */
03125       assert(sz == SIZE_T_SIZE);
03126   }
03127 }
03128 
03129 /* Check properties of malloced chunks at the point they are malloced */
03130 static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
03131   if (mem != 0) {
03132     mchunkptr p = mem2chunk(mem);
03133     size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
03134     do_check_inuse_chunk(m, p);
03135     assert((sz & CHUNK_ALIGN_MASK) == 0);
03136     assert(sz >= MIN_CHUNK_SIZE);
03137     assert(sz >= s);
03138     /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
03139     assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
03140   }
03141 }
03142 
03143 /* Check a tree and its subtrees.  */
03144 static void do_check_tree(mstate m, tchunkptr t) {
03145   tchunkptr head = 0;
03146   tchunkptr u = t;
03147   bindex_t tindex = t->index;
03148   size_t tsize = chunksize(t);
03149   bindex_t idx;
03150   compute_tree_index(tsize, idx);
03151   assert(tindex == idx);
03152   assert(tsize >= MIN_LARGE_SIZE);
03153   assert(tsize >= minsize_for_tree_index(idx));
03154   assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
03155 
03156   do { /* traverse through chain of same-sized nodes */
03157     do_check_any_chunk(m, ((mchunkptr)u));
03158     assert(u->index == tindex);
03159     assert(chunksize(u) == tsize);
03160     assert(!cinuse(u));
03161     assert(!next_pinuse(u));
03162     assert(u->fd->bk == u);
03163     assert(u->bk->fd == u);
03164     if (u->parent == 0) {
03165       assert(u->child[0] == 0);
03166       assert(u->child[1] == 0);
03167     }
03168     else {
03169       assert(head == 0); /* only one node on chain has parent */
03170       head = u;
03171       assert(u->parent != u);
03172       assert (u->parent->child[0] == u ||
03173               u->parent->child[1] == u ||
03174               *((tbinptr*)(u->parent)) == u);
03175       if (u->child[0] != 0) {
03176         assert(u->child[0]->parent == u);
03177         assert(u->child[0] != u);
03178         do_check_tree(m, u->child[0]);
03179       }
03180       if (u->child[1] != 0) {
03181         assert(u->child[1]->parent == u);
03182         assert(u->child[1] != u);
03183         do_check_tree(m, u->child[1]);
03184       }
03185       if (u->child[0] != 0 && u->child[1] != 0) {
03186         assert(chunksize(u->child[0]) < chunksize(u->child[1]));
03187       }
03188     }
03189     u = u->fd;
03190   } while (u != t);
03191   assert(head != 0);
03192 }
03193 
03194 /*  Check all the chunks in a treebin.  */
03195 static void do_check_treebin(mstate m, bindex_t i) {
03196   tbinptr* tb = treebin_at(m, i);
03197   tchunkptr t = *tb;
03198   int empty = (m->treemap & (1U << i)) == 0;
03199   if (t == 0)
03200     assert(empty);
03201   if (!empty)
03202     do_check_tree(m, t);
03203 }
03204 
03205 /*  Check all the chunks in a smallbin.  */
03206 static void do_check_smallbin(mstate m, bindex_t i) {
03207   sbinptr b = smallbin_at(m, i);
03208   mchunkptr p = b->bk;
03209   unsigned int empty = (m->smallmap & (1U << i)) == 0;
03210   if (p == b)
03211     assert(empty);
03212   if (!empty) {
03213     for (; p != b; p = p->bk) {
03214       size_t size = chunksize(p);
03215       mchunkptr q;
03216       /* each chunk claims to be free */
03217       do_check_free_chunk(m, p);
03218       /* chunk belongs in bin */
03219       assert(small_index(size) == i);
03220       assert(p->bk == b || chunksize(p->bk) == chunksize(p));
03221       /* chunk is followed by an inuse chunk */
03222       q = next_chunk(p);
03223       if (q->head != FENCEPOST_HEAD)
03224         do_check_inuse_chunk(m, q);
03225     }
03226   }
03227 }
03228 
03229 /* Find x in a bin. Used in other check functions. */
03230 static int bin_find(mstate m, mchunkptr x) {
03231   size_t size = chunksize(x);
03232   if (is_small(size)) {
03233     bindex_t sidx = small_index(size);
03234     sbinptr b = smallbin_at(m, sidx);
03235     if (smallmap_is_marked(m, sidx)) {
03236       mchunkptr p = b;
03237       do {
03238         if (p == x)
03239           return 1;
03240       } while ((p = p->fd) != b);
03241     }
03242   }
03243   else {
03244     bindex_t tidx;
03245     compute_tree_index(size, tidx);
03246     if (treemap_is_marked(m, tidx)) {
03247       tchunkptr t = *treebin_at(m, tidx);
03248       size_t sizebits = size << leftshift_for_tree_index(tidx);
03249       while (t != 0 && chunksize(t) != size) {
03250         t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
03251         sizebits <<= 1;
03252       }
03253       if (t != 0) {
03254         tchunkptr u = t;
03255         do {
03256           if (u == (tchunkptr)x)
03257             return 1;
03258         } while ((u = u->fd) != t);
03259       }
03260     }
03261   }
03262   return 0;
03263 }
03264 
03265 /* Traverse each chunk and check it; return total */
03266 static size_t traverse_and_check(mstate m) {
03267   size_t sum = 0;
03268   if (is_initialized(m)) {
03269     msegmentptr s = &m->seg;
03270     sum += m->topsize + TOP_FOOT_SIZE;
03271     while (s != 0) {
03272       mchunkptr q = align_as_chunk(s->base);
03273       mchunkptr lastq = 0;
03274       assert(pinuse(q));
03275       while (segment_holds(s, q) &&
03276              q != m->top && q->head != FENCEPOST_HEAD) {
03277         sum += chunksize(q);
03278         if (cinuse(q)) {
03279           assert(!bin_find(m, q));
03280           do_check_inuse_chunk(m, q);
03281         }
03282         else {
03283           assert(q == m->dv || bin_find(m, q));
03284           assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */
03285           do_check_free_chunk(m, q);
03286         }
03287         lastq = q;
03288         q = next_chunk(q);
03289       }
03290       s = s->next;
03291     }
03292   }
03293   return sum;
03294 }
03295 
03296 /* Check all properties of malloc_state. */
03297 static void do_check_malloc_state(mstate m) {
03298   bindex_t i;
03299   size_t total;
03300   /* check bins */
03301   for (i = 0; i < NSMALLBINS; ++i)
03302     do_check_smallbin(m, i);
03303   for (i = 0; i < NTREEBINS; ++i)
03304     do_check_treebin(m, i);
03305 
03306   if (m->dvsize != 0) { /* check dv chunk */
03307     do_check_any_chunk(m, m->dv);
03308     assert(m->dvsize == chunksize(m->dv));
03309     assert(m->dvsize >= MIN_CHUNK_SIZE);
03310     assert(bin_find(m, m->dv) == 0);
03311   }
03312 
03313   if (m->top != 0) {   /* check top chunk */
03314     do_check_top_chunk(m, m->top);
03315     /*assert(m->topsize == chunksize(m->top)); redundant */
03316     assert(m->topsize > 0);
03317     assert(bin_find(m, m->top) == 0);
03318   }
03319 
03320   total = traverse_and_check(m);
03321   assert(total <= m->footprint);
03322   assert(m->footprint <= m->max_footprint);
03323 }
03324 #endif /* DEBUG */
03325 
03326 /* ----------------------------- statistics ------------------------------ */
03327 
03328 #if !NO_MALLINFO
03329 static struct mallinfo internal_mallinfo(mstate m) {
03330   struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
03331   ensure_initialization();
03332   if (!PREACTION(m)) {
03333     check_malloc_state(m);
03334     if (is_initialized(m)) {
03335       size_t nfree = SIZE_T_ONE; /* top always free */
03336       size_t mfree = m->topsize + TOP_FOOT_SIZE;
03337       size_t sum = mfree;
03338       msegmentptr s = &m->seg;
03339       while (s != 0) {
03340         mchunkptr q = align_as_chunk(s->base);
03341         while (segment_holds(s, q) &&
03342                q != m->top && q->head != FENCEPOST_HEAD) {
03343           size_t sz = chunksize(q);
03344           sum += sz;
03345           if (!cinuse(q)) {
03346             mfree += sz;
03347             ++nfree;
03348           }
03349           q = next_chunk(q);
03350         }
03351         s = s->next;
03352       }
03353 
03354       nm.arena    = sum;
03355       nm.ordblks  = nfree;
03356       nm.hblkhd   = m->footprint - sum;
03357       nm.usmblks  = m->max_footprint;
03358       nm.uordblks = m->footprint - mfree;
03359       nm.fordblks = mfree;
03360       nm.keepcost = m->topsize;
03361     }
03362 
03363     POSTACTION(m);
03364   }
03365   return nm;
03366 }
03367 #endif /* !NO_MALLINFO */
03368 
03369 static void internal_malloc_stats(mstate m) {
03370   ensure_initialization();
03371   if (!PREACTION(m)) {
03372     size_t maxfp = 0;
03373     size_t fp = 0;
03374     size_t used = 0;
03375     check_malloc_state(m);
03376     if (is_initialized(m)) {
03377       msegmentptr s = &m->seg;
03378       maxfp = m->max_footprint;
03379       fp = m->footprint;
03380       used = fp - (m->topsize + TOP_FOOT_SIZE);
03381 
03382       while (s != 0) {
03383         mchunkptr q = align_as_chunk(s->base);
03384         while (segment_holds(s, q) &&
03385                q != m->top && q->head != FENCEPOST_HEAD) {
03386           if (!cinuse(q))
03387             used -= chunksize(q);
03388           q = next_chunk(q);
03389         }
03390         s = s->next;
03391       }
03392     }
03393 
03394     fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
03395     fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
03396     fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
03397 
03398     POSTACTION(m);
03399   }
03400 }
03401 
03402 /* ----------------------- Operations on smallbins ----------------------- */
03403 
03404 /*
03405   Various forms of linking and unlinking are defined as macros.  Even
03406   the ones for trees, which are very long but have very short typical
03407   paths.  This is ugly but reduces reliance on inlining support of
03408   compilers.
03409 */
03410 
03411 /* Link a free chunk into a smallbin  */
03412 #define insert_small_chunk(M, P, S) {\
03413   bindex_t I  = small_index(S);\
03414   mchunkptr B = smallbin_at(M, I);\
03415   mchunkptr F = B;\
03416   assert(S >= MIN_CHUNK_SIZE);\
03417   if (!smallmap_is_marked(M, I))\
03418     mark_smallmap(M, I);\
03419   else if (RTCHECK(ok_address(M, B->fd)))\
03420     F = B->fd;\
03421   else {\
03422     CORRUPTION_ERROR_ACTION(M);\
03423   }\
03424   B->fd = P;\
03425   F->bk = P;\
03426   P->fd = F;\
03427   P->bk = B;\
03428 }
03429 
03430 /* Unlink a chunk from a smallbin  */
03431 #define unlink_small_chunk(M, P, S) {\
03432   mchunkptr F = P->fd;\
03433   mchunkptr B = P->bk;\
03434   bindex_t I = small_index(S);\
03435   assert(P != B);\
03436   assert(P != F);\
03437   assert(chunksize(P) == small_index2size(I));\
03438   if (F == B)\
03439     clear_smallmap(M, I);\
03440   else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\
03441                    (B == smallbin_at(M,I) || ok_address(M, B)))) {\
03442     F->bk = B;\
03443     B->fd = F;\
03444   }\
03445   else {\
03446     CORRUPTION_ERROR_ACTION(M);\
03447   }\
03448 }
03449 
03450 /* Unlink the first chunk from a smallbin */
03451 #define unlink_first_small_chunk(M, B, P, I) {\
03452   mchunkptr F = P->fd;\
03453   assert(P != B);\
03454   assert(P != F);\
03455   assert(chunksize(P) == small_index2size(I));\
03456   if (B == F)\
03457     clear_smallmap(M, I);\
03458   else if (RTCHECK(ok_address(M, F))) {\
03459     B->fd = F;\
03460     F->bk = B;\
03461   }\
03462   else {\
03463     CORRUPTION_ERROR_ACTION(M);\
03464   }\
03465 }
03466 
03467 
03468 
03469 /* Replace dv node, binning the old one */
03470 /* Used only when dvsize known to be small */
03471 #define replace_dv(M, P, S) {\
03472   size_t DVS = M->dvsize;\
03473   if (DVS != 0) {\
03474     mchunkptr DV = M->dv;\
03475     assert(is_small(DVS));\
03476     insert_small_chunk(M, DV, DVS);\
03477   }\
03478   M->dvsize = S;\
03479   M->dv = P;\
03480 }
03481 
03482 /* ------------------------- Operations on trees ------------------------- */
03483 
03484 /* Insert chunk into tree */
03485 #define insert_large_chunk(M, X, S) {\
03486   tbinptr* H;\
03487   bindex_t I;\
03488   compute_tree_index(S, I);\
03489   H = treebin_at(M, I);\
03490   X->index = I;\
03491   X->child[0] = X->child[1] = 0;\
03492   if (!treemap_is_marked(M, I)) {\
03493     mark_treemap(M, I);\
03494     *H = X;\
03495     X->parent = (tchunkptr)H;\
03496     X->fd = X->bk = X;\
03497   }\
03498   else {\
03499     tchunkptr T = *H;\
03500     size_t K = S << leftshift_for_tree_index(I);\
03501     for (;;) {\
03502       if (chunksize(T) != S) {\
03503         tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
03504         K <<= 1;\
03505         if (*C != 0)\
03506           T = *C;\
03507         else if (RTCHECK(ok_address(M, C))) {\
03508           *C = X;\
03509           X->parent = T;\
03510           X->fd = X->bk = X;\
03511           break;\
03512         }\
03513         else {\
03514           CORRUPTION_ERROR_ACTION(M);\
03515           break;\
03516         }\
03517       }\
03518       else {\
03519         tchunkptr F = T->fd;\
03520         if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
03521           T->fd = F->bk = X;\
03522           X->fd = F;\
03523           X->bk = T;\
03524           X->parent = 0;\
03525           break;\
03526         }\
03527         else {\
03528           CORRUPTION_ERROR_ACTION(M);\
03529           break;\
03530         }\
03531       }\
03532     }\
03533   }\
03534 }
03535 
03536 /*
03537   Unlink steps:
03538 
03539   1. If x is a chained node, unlink it from its same-sized fd/bk links
03540      and choose its bk node as its replacement.
03541   2. If x was the last node of its size, but not a leaf node, it must
03542      be replaced with a leaf node (not merely one with an open left or
03543      right), to make sure that lefts and rights of descendents
03544      correspond properly to bit masks.  We use the rightmost descendent
03545      of x.  We could use any other leaf, but this is easy to locate and
03546      tends to counteract removal of leftmosts elsewhere, and so keeps
03547      paths shorter than minimally guaranteed.  This doesn't loop much
03548      because on average a node in a tree is near the bottom.
03549   3. If x is the base of a chain (i.e., has parent links) relink
03550      x's parent and children to x's replacement (or null if none).
03551 */
03552 
03553 #define unlink_large_chunk(M, X) {\
03554   tchunkptr XP = X->parent;\
03555   tchunkptr R;\
03556   if (X->bk != X) {\
03557     tchunkptr F = X->fd;\
03558     R = X->bk;\
03559     if (RTCHECK(ok_address(M, F))) {\
03560       F->bk = R;\
03561       R->fd = F;\
03562     }\
03563     else {\
03564       CORRUPTION_ERROR_ACTION(M);\
03565     }\
03566   }\
03567   else {\
03568     tchunkptr* RP;\
03569     if (((R = *(RP = &(X->child[1]))) != 0) ||\
03570         ((R = *(RP = &(X->child[0]))) != 0)) {\
03571       tchunkptr* CP;\
03572       while ((*(CP = &(R->child[1])) != 0) ||\
03573              (*(CP = &(R->child[0])) != 0)) {\
03574         R = *(RP = CP);\
03575       }\
03576       if (RTCHECK(ok_address(M, RP)))\
03577         *RP = 0;\
03578       else {\
03579         CORRUPTION_ERROR_ACTION(M);\
03580       }\
03581     }\
03582   }\
03583   if (XP != 0) {\
03584     tbinptr* H = treebin_at(M, X->index);\
03585     if (X == *H) {\
03586       if ((*H = R) == 0) \
03587         clear_treemap(M, X->index);\
03588     }\
03589     else if (RTCHECK(ok_address(M, XP))) {\
03590       if (XP->child[0] == X) \
03591         XP->child[0] = R;\
03592       else \
03593         XP->child[1] = R;\
03594     }\
03595     else\
03596       CORRUPTION_ERROR_ACTION(M);\
03597     if (R != 0) {\
03598       if (RTCHECK(ok_address(M, R))) {\
03599         tchunkptr C0, C1;\
03600         R->parent = XP;\
03601         if ((C0 = X->child[0]) != 0) {\
03602           if (RTCHECK(ok_address(M, C0))) {\
03603             R->child[0] = C0;\
03604             C0->parent = R;\
03605           }\
03606           else\
03607             CORRUPTION_ERROR_ACTION(M);\
03608         }\
03609         if ((C1 = X->child[1]) != 0) {\
03610           if (RTCHECK(ok_address(M, C1))) {\
03611             R->child[1] = C1;\
03612             C1->parent = R;\
03613           }\
03614           else\
03615             CORRUPTION_ERROR_ACTION(M);\
03616         }\
03617       }\
03618       else\
03619         CORRUPTION_ERROR_ACTION(M);\
03620     }\
03621   }\
03622 }
03623 
03624 /* Relays to large vs small bin operations */
03625 
03626 #define insert_chunk(M, P, S)\
03627   if (is_small(S)) insert_small_chunk(M, P, S)\
03628   else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
03629 
03630 #define unlink_chunk(M, P, S)\
03631   if (is_small(S)) unlink_small_chunk(M, P, S)\
03632   else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
03633 
03634 
03635 /* Relays to internal calls to malloc/free from realloc, memalign etc */
03636 
03637 #if ONLY_MSPACES
03638 #define internal_malloc(m, b) mspace_malloc(m, b)
03639 #define internal_free(m, mem) mspace_free(m,mem);
03640 #else /* ONLY_MSPACES */
03641 #if MSPACES
03642 #define internal_malloc(m, b)\
03643    (m == gm)? dlmalloc(b) : mspace_malloc(m, b)
03644 #define internal_free(m, mem)\
03645    if (m == gm) dlfree(mem); else mspace_free(m,mem);
03646 #else /* MSPACES */
03647 #define internal_malloc(m, b) dlmalloc(b)
03648 #define internal_free(m, mem) dlfree(mem)
03649 #endif /* MSPACES */
03650 #endif /* ONLY_MSPACES */
03651 
03652 /* -----------------------  Direct-mmapping chunks ----------------------- */
03653 
03654 /*
03655   Directly mmapped chunks are set up with an offset to the start of
03656   the mmapped region stored in the prev_foot field of the chunk. This
03657   allows reconstruction of the required argument to MUNMAP when freed,
03658   and also allows adjustment of the returned chunk to meet alignment
03659   requirements (especially in memalign).  There is also enough space
03660   allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain
03661   the PINUSE bit so frees can be checked.
03662 */
03663 
03664 /* Malloc using mmap */
03665 static void* mmap_alloc(mstate m, size_t nb) {
03666   size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
03667   if (mmsize > nb) {     /* Check for wrap around 0 */
03668     char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));
03669     if (mm != CMFAIL) {
03670       size_t offset = align_offset(chunk2mem(mm));
03671       size_t psize = mmsize - offset - MMAP_FOOT_PAD;
03672       mchunkptr p = (mchunkptr)(mm + offset);
03673       p->prev_foot = offset | IS_MMAPPED_BIT;
03674       (p)->head = (psize|CINUSE_BIT);
03675       mark_inuse_foot(m, p, psize);
03676       chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
03677       chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
03678 
03679       if (mm < m->least_addr)
03680         m->least_addr = mm;
03681       if ((m->footprint += mmsize) > m->max_footprint)
03682         m->max_footprint = m->footprint;
03683       assert(is_aligned(chunk2mem(p)));
03684       check_mmapped_chunk(m, p);
03685       return chunk2mem(p);
03686     }
03687   }
03688   return 0;
03689 }
03690 
03691 /* Realloc using mmap */
03692 static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) {
03693   size_t oldsize = chunksize(oldp);
03694   if (is_small(nb)) /* Can't shrink mmap regions below small size */
03695     return 0;
03696   /* Keep old chunk if big enough but not too big */
03697   if (oldsize >= nb + SIZE_T_SIZE &&
03698       (oldsize - nb) <= (mparams.granularity << 1))
03699     return oldp;
03700   else {
03701     size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT;
03702     size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
03703     size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
03704     char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
03705                                   oldmmsize, newmmsize, 1);
03706     if (cp != CMFAIL) {
03707       mchunkptr newp = (mchunkptr)(cp + offset);
03708       size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
03709       newp->head = (psize|CINUSE_BIT);
03710       mark_inuse_foot(m, newp, psize);
03711       chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
03712       chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
03713 
03714       if (cp < m->least_addr)
03715         m->least_addr = cp;
03716       if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
03717         m->max_footprint = m->footprint;
03718       check_mmapped_chunk(m, newp);
03719       return newp;
03720     }
03721   }
03722   return 0;
03723 }
03724 
03725 /* -------------------------- mspace management -------------------------- */
03726 
03727 /* Initialize top chunk and its size */
03728 static void init_top(mstate m, mchunkptr p, size_t psize) {
03729   /* Ensure alignment */
03730   size_t offset = align_offset(chunk2mem(p));
03731   p = (mchunkptr)((char*)p + offset);
03732   psize -= offset;
03733 
03734   m->top = p;
03735   m->topsize = psize;
03736   p->head = psize | PINUSE_BIT;
03737   /* set size of fake trailing chunk holding overhead space only once */
03738   chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
03739   m->trim_check = mparams.trim_threshold; /* reset on each update */
03740 }
03741 
03742 /* Initialize bins for a new mstate that is otherwise zeroed out */
03743 static void init_bins(mstate m) {
03744   /* Establish circular links for smallbins */
03745   bindex_t i;
03746   for (i = 0; i < NSMALLBINS; ++i) {
03747     sbinptr bin = smallbin_at(m,i);
03748     bin->fd = bin->bk = bin;
03749   }
03750 }
03751 
03752 #if PROCEED_ON_ERROR
03753 
03754 /* default corruption action */
03755 static void reset_on_error(mstate m) {
03756   int i;
03757   ++malloc_corruption_error_count;
03758   /* Reinitialize fields to forget about all memory */
03759   m->smallbins = m->treebins = 0;
03760   m->dvsize = m->topsize = 0;
03761   m->seg.base = 0;
03762   m->seg.size = 0;
03763   m->seg.next = 0;
03764   m->top = m->dv = 0;
03765   for (i = 0; i < NTREEBINS; ++i)
03766     *treebin_at(m, i) = 0;
03767   init_bins(m);
03768 }
03769 #endif /* PROCEED_ON_ERROR */
03770 
03771 /* Allocate chunk and prepend remainder with chunk in successor base. */
03772 static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
03773                            size_t nb) {
03774   mchunkptr p = align_as_chunk(newbase);
03775   mchunkptr oldfirst = align_as_chunk(oldbase);
03776   size_t psize = (char*)oldfirst - (char*)p;
03777   mchunkptr q = chunk_plus_offset(p, nb);
03778   size_t qsize = psize - nb;
03779   set_size_and_pinuse_of_inuse_chunk(m, p, nb);
03780 
03781   assert((char*)oldfirst > (char*)q);
03782   assert(pinuse(oldfirst));
03783   assert(qsize >= MIN_CHUNK_SIZE);
03784 
03785   /* consolidate remainder with first chunk of old base */
03786   if (oldfirst == m->top) {
03787     size_t tsize = m->topsize += qsize;
03788     m->top = q;
03789     q->head = tsize | PINUSE_BIT;
03790     check_top_chunk(m, q);
03791   }
03792   else if (oldfirst == m->dv) {
03793     size_t dsize = m->dvsize += qsize;
03794     m->dv = q;
03795     set_size_and_pinuse_of_free_chunk(q, dsize);
03796   }
03797   else {
03798     if (!cinuse(oldfirst)) {
03799       size_t nsize = chunksize(oldfirst);
03800       unlink_chunk(m, oldfirst, nsize);
03801       oldfirst = chunk_plus_offset(oldfirst, nsize);
03802       qsize += nsize;
03803     }
03804     set_free_with_pinuse(q, qsize, oldfirst);
03805     insert_chunk(m, q, qsize);
03806     check_free_chunk(m, q);
03807   }
03808 
03809   check_malloced_chunk(m, chunk2mem(p), nb);
03810   return chunk2mem(p);
03811 }
03812 
03813 /* Add a segment to hold a new noncontiguous region */
03814 static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
03815   /* Determine locations and sizes of segment, fenceposts, old top */
03816   char* old_top = (char*)m->top;
03817   msegmentptr oldsp = segment_holding(m, old_top);
03818   char* old_end = oldsp->base + oldsp->size;
03819   size_t ssize = pad_request(sizeof(struct malloc_segment));
03820   char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
03821   size_t offset = align_offset(chunk2mem(rawsp));
03822   char* asp = rawsp + offset;
03823   char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
03824   mchunkptr sp = (mchunkptr)csp;
03825   msegmentptr ss = (msegmentptr)(chunk2mem(sp));
03826   mchunkptr tnext = chunk_plus_offset(sp, ssize);
03827   mchunkptr p = tnext;
03828   int nfences = 0;
03829 
03830   /* reset top to new space */
03831   init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
03832 
03833   /* Set up segment record */
03834   assert(is_aligned(ss));
03835   set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
03836   *ss = m->seg; /* Push current record */
03837   m->seg.base = tbase;
03838   m->seg.size = tsize;
03839   m->seg.sflags = mmapped;
03840   m->seg.next = ss;
03841 
03842   /* Insert trailing fenceposts */
03843   for (;;) {
03844     mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
03845     p->head = FENCEPOST_HEAD;
03846     ++nfences;
03847     if ((char*)(&(nextp->head)) < old_end)
03848       p = nextp;
03849     else
03850       break;
03851   }
03852   assert(nfences >= 2);
03853 
03854   /* Insert the rest of old top into a bin as an ordinary free chunk */
03855   if (csp != old_top) {
03856     mchunkptr q = (mchunkptr)old_top;
03857     size_t psize = csp - old_top;
03858     mchunkptr tn = chunk_plus_offset(q, psize);
03859     set_free_with_pinuse(q, psize, tn);
03860     insert_chunk(m, q, psize);
03861   }
03862 
03863   check_top_chunk(m, m->top);
03864 }
03865 
03866 /* -------------------------- System allocation -------------------------- */
03867 
03868 /* Get memory from system using MORECORE or MMAP */
03869 static void* sys_alloc(mstate m, size_t nb) {
03870   char* tbase = CMFAIL;
03871   size_t tsize = 0;
03872   flag_t mmap_flag = 0;
03873 
03874   ensure_initialization();
03875 
03876   /* Directly map large chunks */
03877   if (use_mmap(m) && nb >= mparams.mmap_threshold) {
03878     void* mem = mmap_alloc(m, nb);
03879     if (mem != 0)
03880       return mem;
03881   }
03882 
03883   /*
03884     Try getting memory in any of three ways (in most-preferred to
03885     least-preferred order):
03886     1. A call to MORECORE that can normally contiguously extend memory.
03887        (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
03888        or main space is mmapped or a previous contiguous call failed)
03889     2. A call to MMAP new space (disabled if not HAVE_MMAP).
03890        Note that under the default settings, if MORECORE is unable to
03891        fulfill a request, and HAVE_MMAP is true, then mmap is
03892        used as a noncontiguous system allocator. This is a useful backup
03893        strategy for systems with holes in address spaces -- in this case
03894        sbrk cannot contiguously expand the heap, but mmap may be able to
03895        find space.
03896     3. A call to MORECORE that cannot usually contiguously extend memory.
03897        (disabled if not HAVE_MORECORE)
03898 
03899    In all cases, we need to request enough bytes from system to ensure 
03900    we can malloc nb bytes upon success, so pad with enough space for 
03901    top_foot, plus alignment-pad to make sure we don't lose bytes if 
03902    not on boundary, and round this up to a granularity unit.
03903   */
03904 
03905   if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
03906     char* br = CMFAIL;
03907     msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
03908     size_t asize = 0;
03909     ACQUIRE_MALLOC_GLOBAL_LOCK();
03910 
03911     if (ss == 0) {  /* First time through or recovery */
03912       char* base = (char*)CALL_MORECORE(0);
03913       if (base != CMFAIL) {
03914         asize = granularity_align(nb + SYS_ALLOC_PADDING);
03915         /* Adjust to end on a page boundary */
03916         if (!is_page_aligned(base))
03917           asize += (page_align((size_t)base) - (size_t)base);
03918         /* Can't call MORECORE if size is negative when treated as signed */
03919         if (asize < HALF_MAX_SIZE_T &&
03920             (br = (char*)(CALL_MORECORE(asize))) == base) {
03921           tbase = base;
03922           tsize = asize;
03923         }
03924       }
03925     }
03926     else {
03927       /* Subtract out existing available top space from MORECORE request. */
03928       asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);
03929       /* Use mem here only if it did continuously extend old space */
03930       if (asize < HALF_MAX_SIZE_T &&
03931           (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {
03932         tbase = br;
03933         tsize = asize;
03934       }
03935     }
03936 
03937     if (tbase == CMFAIL) {    /* Cope with partial failure */
03938       if (br != CMFAIL) {    /* Try to use/extend the space we did get */
03939         if (asize < HALF_MAX_SIZE_T &&
03940             asize < nb + SYS_ALLOC_PADDING) {
03941           size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize);
03942           if (esize < HALF_MAX_SIZE_T) {
03943             char* end = (char*)CALL_MORECORE(esize);
03944             if (end != CMFAIL)
03945               asize += esize;
03946             else {            /* Can't use; try to release */
03947               (void) CALL_MORECORE(-asize);
03948               br = CMFAIL;
03949             }
03950           }
03951         }
03952       }
03953       if (br != CMFAIL) {    /* Use the space we did get */
03954         tbase = br;
03955         tsize = asize;
03956       }
03957       else
03958         disable_contiguous(m); /* Don't try contiguous path in the future */
03959     }
03960 
03961     RELEASE_MALLOC_GLOBAL_LOCK();
03962   }
03963 
03964   if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
03965     size_t rsize = granularity_align(nb + SYS_ALLOC_PADDING);
03966     if (rsize > nb) { /* Fail if wraps around zero */
03967       char* mp = (char*)(CALL_MMAP(rsize));
03968       if (mp != CMFAIL) {
03969         tbase = mp;
03970         tsize = rsize;
03971         mmap_flag = IS_MMAPPED_BIT;
03972       }
03973     }
03974   }
03975 
03976   if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
03977     size_t asize = granularity_align(nb + SYS_ALLOC_PADDING);
03978     if (asize < HALF_MAX_SIZE_T) {
03979       char* br = CMFAIL;
03980       char* end = CMFAIL;
03981       ACQUIRE_MALLOC_GLOBAL_LOCK();
03982       br = (char*)(CALL_MORECORE(asize));
03983       end = (char*)(CALL_MORECORE(0));
03984       RELEASE_MALLOC_GLOBAL_LOCK();
03985       if (br != CMFAIL && end != CMFAIL && br < end) {
03986         size_t ssize = end - br;
03987         if (ssize > nb + TOP_FOOT_SIZE) {
03988           tbase = br;
03989           tsize = ssize;
03990         }
03991       }
03992     }
03993   }
03994 
03995   if (tbase != CMFAIL) {
03996 
03997     if ((m->footprint += tsize) > m->max_footprint)
03998       m->max_footprint = m->footprint;
03999 
04000     if (!is_initialized(m)) { /* first-time initialization */
04001       m->seg.base = m->least_addr = tbase;
04002       m->seg.size = tsize;
04003       m->seg.sflags = mmap_flag;
04004       m->magic = mparams.magic;
04005       m->release_checks = MAX_RELEASE_CHECK_RATE;
04006       init_bins(m);
04007 #if !ONLY_MSPACES
04008       if (is_global(m))
04009         init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
04010       else
04011 #endif
04012       {
04013         /* Offset top by embedded malloc_state */
04014         mchunkptr mn = next_chunk(mem2chunk(m));
04015         init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
04016       }
04017     }
04018 
04019     else {
04020       /* Try to merge with an existing segment */
04021       msegmentptr sp = &m->seg;
04022       /* Only consider most recent segment if traversal suppressed */
04023       while (sp != 0 && tbase != sp->base + sp->size)
04024         sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
04025       if (sp != 0 &&
04026           !is_extern_segment(sp) &&
04027           (sp->sflags & IS_MMAPPED_BIT) == mmap_flag &&
04028           segment_holds(sp, m->top)) { /* append */
04029         sp->size += tsize;
04030         init_top(m, m->top, m->topsize + tsize);
04031       }
04032       else {
04033         if (tbase < m->least_addr)
04034           m->least_addr = tbase;
04035         sp = &m->seg;
04036         while (sp != 0 && sp->base != tbase + tsize)
04037           sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
04038         if (sp != 0 &&
04039             !is_extern_segment(sp) &&
04040             (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) {
04041           char* oldbase = sp->base;
04042           sp->base = tbase;
04043           sp->size += tsize;
04044           return prepend_alloc(m, tbase, oldbase, nb);
04045         }
04046         else
04047           add_segment(m, tbase, tsize, mmap_flag);
04048       }
04049     }
04050 
04051     if (nb < m->topsize) { /* Allocate from new or extended top space */
04052       size_t rsize = m->topsize -= nb;
04053       mchunkptr p = m->top;
04054       mchunkptr r = m->top = chunk_plus_offset(p, nb);
04055       r->head = rsize | PINUSE_BIT;
04056       set_size_and_pinuse_of_inuse_chunk(m, p, nb);
04057       check_top_chunk(m, m->top);
04058       check_malloced_chunk(m, chunk2mem(p), nb);
04059       return chunk2mem(p);
04060     }
04061   }
04062 
04063   MALLOC_FAILURE_ACTION;
04064   return 0;
04065 }
04066 
04067 /* -----------------------  system deallocation -------------------------- */
04068 
04069 /* Unmap and unlink any mmapped segments that don't contain used chunks */
04070 static size_t release_unused_segments(mstate m) {
04071   size_t released = 0;
04072   int nsegs = 0;
04073   msegmentptr pred = &m->seg;
04074   msegmentptr sp = pred->next;
04075   while (sp != 0) {
04076     char* base = sp->base;
04077     size_t size = sp->size;
04078     msegmentptr next = sp->next;
04079     ++nsegs;
04080     if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
04081       mchunkptr p = align_as_chunk(base);
04082       size_t psize = chunksize(p);
04083       /* Can unmap if first chunk holds entire segment and not pinned */
04084       if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
04085         tchunkptr tp = (tchunkptr)p;
04086         assert(segment_holds(sp, (char*)sp));
04087         if (p == m->dv) {
04088           m->dv = 0;
04089           m->dvsize = 0;
04090         }
04091         else {
04092           unlink_large_chunk(m, tp);
04093         }
04094         if (CALL_MUNMAP(base, size) == 0) {
04095           released += size;
04096           m->footprint -= size;
04097           /* unlink obsoleted record */
04098           sp = pred;
04099           sp->next = next;
04100         }
04101         else { /* back out if cannot unmap */
04102           insert_large_chunk(m, tp, psize);
04103         }
04104       }
04105     }
04106     if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */
04107       break;
04108     pred = sp;
04109     sp = next;
04110   }
04111   /* Reset check counter */
04112   m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)?
04113                        nsegs : MAX_RELEASE_CHECK_RATE);
04114   return released;
04115 }
04116 
04117 static int sys_trim(mstate m, size_t pad) {
04118   size_t released = 0;
04119   ensure_initialization();
04120   if (pad < MAX_REQUEST && is_initialized(m)) {
04121     pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
04122 
04123     if (m->topsize > pad) {
04124       /* Shrink top space in granularity-size units, keeping at least one */
04125       size_t unit = mparams.granularity;
04126       size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
04127                       SIZE_T_ONE) * unit;
04128       msegmentptr sp = segment_holding(m, (char*)m->top);
04129 
04130       if (!is_extern_segment(sp)) {
04131         if (is_mmapped_segment(sp)) {
04132           if (HAVE_MMAP &&
04133               sp->size >= extra &&
04134               !has_segment_link(m, sp)) { /* can't shrink if pinned */
04135             size_t newsize = sp->size - extra;
04136             /* Prefer mremap, fall back to munmap */
04137             if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
04138                 (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
04139               released = extra;
04140             }
04141           }
04142         }
04143         else if (HAVE_MORECORE) {
04144           if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
04145             extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
04146           ACQUIRE_MALLOC_GLOBAL_LOCK();
04147           {
04148             /* Make sure end of memory is where we last set it. */
04149             char* old_br = (char*)(CALL_MORECORE(0));
04150             if (old_br == sp->base + sp->size) {
04151               char* rel_br = (char*)(CALL_MORECORE(-extra));
04152               char* new_br = (char*)(CALL_MORECORE(0));
04153               if (rel_br != CMFAIL && new_br < old_br)
04154                 released = old_br - new_br;
04155             }
04156           }
04157           RELEASE_MALLOC_GLOBAL_LOCK();
04158         }
04159       }
04160 
04161       if (released != 0) {
04162         sp->size -= released;
04163         m->footprint -= released;
04164         init_top(m, m->top, m->topsize - released);
04165         check_top_chunk(m, m->top);
04166       }
04167     }
04168 
04169     /* Unmap any unused mmapped segments */
04170     if (HAVE_MMAP)
04171       released += release_unused_segments(m);
04172 
04173     /* On failure, disable autotrim to avoid repeated failed future calls */
04174     if (released == 0 && m->topsize > m->trim_check)
04175       m->trim_check = MAX_SIZE_T;
04176   }
04177 
04178   return (released != 0)? 1 : 0;
04179 }
04180 
04181 
04182 /* ---------------------------- malloc support --------------------------- */
04183 
04184 /* allocate a large request from the best fitting chunk in a treebin */
04185 static void* tmalloc_large(mstate m, size_t nb) {
04186   tchunkptr v = 0;
04187   size_t rsize = -nb; /* Unsigned negation */
04188   tchunkptr t;
04189   bindex_t idx;
04190   compute_tree_index(nb, idx);
04191   if ((t = *treebin_at(m, idx)) != 0) {
04192     /* Traverse tree for this bin looking for node with size == nb */
04193     size_t sizebits = nb << leftshift_for_tree_index(idx);
04194     tchunkptr rst = 0;  /* The deepest untaken right subtree */
04195     for (;;) {
04196       tchunkptr rt;
04197       size_t trem = chunksize(t) - nb;
04198       if (trem < rsize) {
04199         v = t;
04200         if ((rsize = trem) == 0)
04201           break;
04202       }
04203       rt = t->child[1];
04204       t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
04205       if (rt != 0 && rt != t)
04206         rst = rt;
04207       if (t == 0) {
04208         t = rst; /* set t to least subtree holding sizes > nb */
04209         break;
04210       }
04211       sizebits <<= 1;
04212     }
04213   }
04214   if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
04215     binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
04216     if (leftbits != 0) {
04217       bindex_t i;
04218       binmap_t leastbit = least_bit(leftbits);
04219       compute_bit2idx(leastbit, i);
04220       t = *treebin_at(m, i);
04221     }
04222   }
04223 
04224   while (t != 0) { /* find smallest of tree or subtree */
04225     size_t trem = chunksize(t) - nb;
04226     if (trem < rsize) {
04227       rsize = trem;
04228       v = t;
04229     }
04230     t = leftmost_child(t);
04231   }
04232 
04233   /*  If dv is a better fit, return 0 so malloc will use it */
04234   if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
04235     if (RTCHECK(ok_address(m, v))) { /* split */
04236       mchunkptr r = chunk_plus_offset(v, nb);
04237       assert(chunksize(v) == rsize + nb);
04238       if (RTCHECK(ok_next(v, r))) {
04239         unlink_large_chunk(m, v);
04240         if (rsize < MIN_CHUNK_SIZE)
04241           set_inuse_and_pinuse(m, v, (rsize + nb));
04242         else {
04243           set_size_and_pinuse_of_inuse_chunk(m, v, nb);
04244           set_size_and_pinuse_of_free_chunk(r, rsize);
04245           insert_chunk(m, r, rsize);
04246         }
04247         return chunk2mem(v);
04248       }
04249     }
04250     CORRUPTION_ERROR_ACTION(m);
04251   }
04252   return 0;
04253 }
04254 
04255 /* allocate a small request from the best fitting chunk in a treebin */
04256 static void* tmalloc_small(mstate m, size_t nb) {
04257   tchunkptr t, v;
04258   size_t rsize;
04259   bindex_t i;
04260   binmap_t leastbit = least_bit(m->treemap);
04261   compute_bit2idx(leastbit, i);
04262   v = t = *treebin_at(m, i);
04263   rsize = chunksize(t) - nb;
04264 
04265   while ((t = leftmost_child(t)) != 0) {
04266     size_t trem = chunksize(t) - nb;
04267     if (trem < rsize) {
04268       rsize = trem;
04269       v = t;
04270     }
04271   }
04272 
04273   if (RTCHECK(ok_address(m, v))) {
04274     mchunkptr r = chunk_plus_offset(v, nb);
04275     assert(chunksize(v) == rsize + nb);
04276     if (RTCHECK(ok_next(v, r))) {
04277       unlink_large_chunk(m, v);
04278       if (rsize < MIN_CHUNK_SIZE)
04279         set_inuse_and_pinuse(m, v, (rsize + nb));
04280       else {
04281         set_size_and_pinuse_of_inuse_chunk(m, v, nb);
04282         set_size_and_pinuse_of_free_chunk(r, rsize);
04283         replace_dv(m, r, rsize);
04284       }
04285       return chunk2mem(v);
04286     }
04287   }
04288 
04289   CORRUPTION_ERROR_ACTION(m);
04290   return 0;
04291 }
04292 
04293 /* --------------------------- realloc support --------------------------- */
04294 
04295 static void* internal_realloc(mstate m, void* oldmem, size_t bytes) {
04296   if (bytes >= MAX_REQUEST) {
04297     MALLOC_FAILURE_ACTION;
04298     return 0;
04299   }
04300   if (!PREACTION(m)) {
04301     mchunkptr oldp = mem2chunk(oldmem);
04302     size_t oldsize = chunksize(oldp);
04303     mchunkptr next = chunk_plus_offset(oldp, oldsize);
04304     mchunkptr newp = 0;
04305     void* extra = 0;
04306 
04307     /* Try to either shrink or extend into top. Else malloc-copy-free */
04308 
04309     if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) &&
04310                 ok_next(oldp, next) && ok_pinuse(next))) {
04311       size_t nb = request2size(bytes);
04312       if (is_mmapped(oldp))
04313         newp = mmap_resize(m, oldp, nb);
04314       else if (oldsize >= nb) { /* already big enough */
04315         size_t rsize = oldsize - nb;
04316         newp = oldp;
04317         if (rsize >= MIN_CHUNK_SIZE) {
04318           mchunkptr remainder = chunk_plus_offset(newp, nb);
04319           set_inuse(m, newp, nb);
04320           set_inuse(m, remainder, rsize);
04321           extra = chunk2mem(remainder);
04322         }
04323       }
04324       else if (next == m->top && oldsize + m->topsize > nb) {
04325         /* Expand into top */
04326         size_t newsize = oldsize + m->topsize;
04327         size_t newtopsize = newsize - nb;
04328         mchunkptr newtop = chunk_plus_offset(oldp, nb);
04329         set_inuse(m, oldp, nb);
04330         newtop->head = newtopsize |PINUSE_BIT;
04331         m->top = newtop;
04332         m->topsize = newtopsize;
04333         newp = oldp;
04334       }
04335     }
04336     else {
04337       USAGE_ERROR_ACTION(m, oldmem);
04338       POSTACTION(m);
04339       return 0;
04340     }
04341 
04342     POSTACTION(m);
04343 
04344     if (newp != 0) {
04345       if (extra != 0) {
04346         internal_free(m, extra);
04347       }
04348       check_inuse_chunk(m, newp);
04349       return chunk2mem(newp);
04350     }
04351     else {
04352       void* newmem = internal_malloc(m, bytes);
04353       if (newmem != 0) {
04354         size_t oc = oldsize - overhead_for(oldp);
04355         memcpy(newmem, oldmem, (oc < bytes)? oc : bytes);
04356         internal_free(m, oldmem);
04357       }
04358       return newmem;
04359     }
04360   }
04361   return 0;
04362 }
04363 
04364 /* --------------------------- memalign support -------------------------- */
04365 
04366 static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
04367   if (alignment <= MALLOC_ALIGNMENT)    /* Can just use malloc */
04368     return internal_malloc(m, bytes);
04369   if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
04370     alignment = MIN_CHUNK_SIZE;
04371   if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
04372     size_t a = MALLOC_ALIGNMENT << 1;
04373     while (a < alignment) a <<= 1;
04374     alignment = a;
04375   }
04376 
04377   if (bytes >= MAX_REQUEST - alignment) {
04378     if (m != 0)  { /* Test isn't needed but avoids compiler warning */
04379       MALLOC_FAILURE_ACTION;
04380     }
04381   }
04382   else {
04383     size_t nb = request2size(bytes);
04384     size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
04385     char* mem = (char*)internal_malloc(m, req);
04386     if (mem != 0) {
04387       void* leader = 0;
04388       void* trailer = 0;
04389       mchunkptr p = mem2chunk(mem);
04390 
04391       if (PREACTION(m)) return 0;
04392       if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */
04393         /*
04394           Find an aligned spot inside chunk.  Since we need to give
04395           back leading space in a chunk of at least MIN_CHUNK_SIZE, if
04396           the first calculation places us at a spot with less than
04397           MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
04398           We've allocated enough total room so that this is always
04399           possible.
04400         */
04401         char* br = (char*)mem2chunk((size_t)(((size_t)(mem +
04402                                                        alignment -
04403                                                        SIZE_T_ONE)) &
04404                                              -alignment));
04405         char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
04406           br : br+alignment;
04407         mchunkptr newp = (mchunkptr)pos;
04408         size_t leadsize = pos - (char*)(p);
04409         size_t newsize = chunksize(p) - leadsize;
04410 
04411         if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
04412           newp->prev_foot = p->prev_foot + leadsize;
04413           newp->head = (newsize|CINUSE_BIT);
04414         }
04415         else { /* Otherwise, give back leader, use the rest */
04416           set_inuse(m, newp, newsize);
04417           set_inuse(m, p, leadsize);
04418           leader = chunk2mem(p);
04419         }
04420         p = newp;
04421       }
04422 
04423       /* Give back spare room at the end */
04424       if (!is_mmapped(p)) {
04425         size_t size = chunksize(p);
04426         if (size > nb + MIN_CHUNK_SIZE) {
04427           size_t remainder_size = size - nb;
04428           mchunkptr remainder = chunk_plus_offset(p, nb);
04429           set_inuse(m, p, nb);
04430           set_inuse(m, remainder, remainder_size);
04431           trailer = chunk2mem(remainder);
04432         }
04433       }
04434 
04435       assert (chunksize(p) >= nb);
04436       assert((((size_t)(chunk2mem(p))) % alignment) == 0);
04437       check_inuse_chunk(m, p);
04438       POSTACTION(m);
04439       if (leader != 0) {
04440         internal_free(m, leader);
04441       }
04442       if (trailer != 0) {
04443         internal_free(m, trailer);
04444       }
04445       return chunk2mem(p);
04446     }
04447   }
04448   return 0;
04449 }
04450 
04451 /* ------------------------ comalloc/coalloc support --------------------- */
04452 
04453 static void** ialloc(mstate m,
04454                      size_t n_elements,
04455                      size_t* sizes,
04456                      int opts,
04457                      void* chunks[]) {
04458   /*
04459     This provides common support for independent_X routines, handling
04460     all of the combinations that can result.
04461 
04462     The opts arg has:
04463     bit 0 set if all elements are same size (using sizes[0])
04464     bit 1 set if elements should be zeroed
04465   */
04466 
04467   size_t    element_size;   /* chunksize of each element, if all same */
04468   size_t    contents_size;  /* total size of elements */
04469   size_t    array_size;     /* request size of pointer array */
04470   void*     mem;            /* malloced aggregate space */
04471   mchunkptr p;              /* corresponding chunk */
04472   size_t    remainder_size; /* remaining bytes while splitting */
04473   void**    marray;         /* either "chunks" or malloced ptr array */
04474   mchunkptr array_chunk;    /* chunk for malloced ptr array */
04475   flag_t    was_enabled;    /* to disable mmap */
04476   size_t    size;
04477   size_t    i;
04478 
04479   ensure_initialization();
04480   /* compute array length, if needed */
04481   if (chunks != 0) {
04482     if (n_elements == 0)
04483       return chunks; /* nothing to do */
04484     marray = chunks;
04485     array_size = 0;
04486   }
04487   else {
04488     /* if empty req, must still return chunk representing empty array */
04489     if (n_elements == 0)
04490       return (void**)internal_malloc(m, 0);
04491     marray = 0;
04492     array_size = request2size(n_elements * (sizeof(void*)));
04493   }
04494 
04495   /* compute total element size */
04496   if (opts & 0x1) { /* all-same-size */
04497     element_size = request2size(*sizes);
04498     contents_size = n_elements * element_size;
04499   }
04500   else { /* add up all the sizes */
04501     element_size = 0;
04502     contents_size = 0;
04503     for (i = 0; i != n_elements; ++i)
04504       contents_size += request2size(sizes[i]);
04505   }
04506 
04507   size = contents_size + array_size;
04508 
04509   /*
04510      Allocate the aggregate chunk.  First disable direct-mmapping so
04511      malloc won't use it, since we would not be able to later
04512      free/realloc space internal to a segregated mmap region.
04513   */
04514   was_enabled = use_mmap(m);
04515   disable_mmap(m);
04516   mem = internal_malloc(m, size - CHUNK_OVERHEAD);
04517   if (was_enabled)
04518     enable_mmap(m);
04519   if (mem == 0)
04520     return 0;
04521 
04522   if (PREACTION(m)) return 0;
04523   p = mem2chunk(mem);
04524   remainder_size = chunksize(p);
04525 
04526   assert(!is_mmapped(p));
04527 
04528   if (opts & 0x2) {       /* optionally clear the elements */
04529     memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
04530   }
04531 
04532   /* If not provided, allocate the pointer array as final part of chunk */
04533   if (marray == 0) {
04534     size_t  array_chunk_size;
04535     array_chunk = chunk_plus_offset(p, contents_size);
04536     array_chunk_size = remainder_size - contents_size;
04537     marray = (void**) (chunk2mem(array_chunk));
04538     set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
04539     remainder_size = contents_size;
04540   }
04541 
04542   /* split out elements */
04543   for (i = 0; ; ++i) {
04544     marray[i] = chunk2mem(p);
04545     if (i != n_elements-1) {
04546       if (element_size != 0)
04547         size = element_size;
04548       else
04549         size = request2size(sizes[i]);
04550       remainder_size -= size;
04551       set_size_and_pinuse_of_inuse_chunk(m, p, size);
04552       p = chunk_plus_offset(p, size);
04553     }
04554     else { /* the final element absorbs any overallocation slop */
04555       set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
04556       break;
04557     }
04558   }
04559 
04560 #if DEBUG
04561   if (marray != chunks) {
04562     /* final element must have exactly exhausted chunk */
04563     if (element_size != 0) {
04564       assert(remainder_size == element_size);
04565     }
04566     else {
04567       assert(remainder_size == request2size(sizes[i]));
04568     }
04569     check_inuse_chunk(m, mem2chunk(marray));
04570   }
04571   for (i = 0; i != n_elements; ++i)
04572     check_inuse_chunk(m, mem2chunk(marray[i]));
04573 
04574 #endif /* DEBUG */
04575 
04576   POSTACTION(m);
04577   return marray;
04578 }
04579 
04580 
04581 /* -------------------------- public routines ---------------------------- */
04582 
04583 #if !ONLY_MSPACES
04584 
04585 void* dlmalloc(size_t bytes) {
04586   /*
04587      Basic algorithm:
04588      If a small request (< 256 bytes minus per-chunk overhead):
04589        1. If one exists, use a remainderless chunk in associated smallbin.
04590           (Remainderless means that there are too few excess bytes to
04591           represent as a chunk.)
04592        2. If it is big enough, use the dv chunk, which is normally the
04593           chunk adjacent to the one used for the most recent small request.
04594        3. If one exists, split the smallest available chunk in a bin,
04595           saving remainder in dv.
04596        4. If it is big enough, use the top chunk.
04597        5. If available, get memory from system and use it
04598      Otherwise, for a large request:
04599        1. Find the smallest available binned chunk that fits, and use it
04600           if it is better fitting than dv chunk, splitting if necessary.
04601        2. If better fitting than any binned chunk, use the dv chunk.
04602        3. If it is big enough, use the top chunk.
04603        4. If request size >= mmap threshold, try to directly mmap this chunk.
04604        5. If available, get memory from system and use it
04605 
04606      The ugly goto's here ensure that postaction occurs along all paths.
04607   */
04608 
04609 #if USE_LOCKS
04610   ensure_initialization(); /* initialize in sys_alloc if not using locks */
04611 #endif
04612 
04613   if (!PREACTION(gm)) {
04614     void* mem;
04615     size_t nb;
04616     if (bytes <= MAX_SMALL_REQUEST) {
04617       bindex_t idx;
04618       binmap_t smallbits;
04619       nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
04620       idx = small_index(nb);
04621       smallbits = gm->smallmap >> idx;
04622 
04623       if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
04624         mchunkptr b, p;
04625         idx += ~smallbits & 1;       /* Uses next bin if idx empty */
04626         b = smallbin_at(gm, idx);
04627         p = b->fd;
04628         assert(chunksize(p) == small_index2size(idx));
04629         unlink_first_small_chunk(gm, b, p, idx);
04630         set_inuse_and_pinuse(gm, p, small_index2size(idx));
04631         mem = chunk2mem(p);
04632         check_malloced_chunk(gm, mem, nb);
04633         goto postaction;
04634       }
04635 
04636       else if (nb > gm->dvsize) {
04637         if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
04638           mchunkptr b, p, r;
04639           size_t rsize;
04640           bindex_t i;
04641           binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
04642           binmap_t leastbit = least_bit(leftbits);
04643           compute_bit2idx(leastbit, i);
04644           b = smallbin_at(gm, i);
04645           p = b->fd;
04646           assert(chunksize(p) == small_index2size(i));
04647           unlink_first_small_chunk(gm, b, p, i);
04648           rsize = small_index2size(i) - nb;
04649           /* Fit here cannot be remainderless if 4byte sizes */
04650           if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
04651             set_inuse_and_pinuse(gm, p, small_index2size(i));
04652           else {
04653             set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
04654             r = chunk_plus_offset(p, nb);
04655             set_size_and_pinuse_of_free_chunk(r, rsize);
04656             replace_dv(gm, r, rsize);
04657           }
04658           mem = chunk2mem(p);
04659           check_malloced_chunk(gm, mem, nb);
04660           goto postaction;
04661         }
04662 
04663         else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
04664           check_malloced_chunk(gm, mem, nb);
04665           goto postaction;
04666         }
04667       }
04668     }
04669     else if (bytes >= MAX_REQUEST)
04670       nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
04671     else {
04672       nb = pad_request(bytes);
04673       if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
04674         check_malloced_chunk(gm, mem, nb);
04675         goto postaction;
04676       }
04677     }
04678 
04679     if (nb <= gm->dvsize) {
04680       size_t rsize = gm->dvsize - nb;
04681       mchunkptr p = gm->dv;
04682       if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
04683         mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
04684         gm->dvsize = rsize;
04685         set_size_and_pinuse_of_free_chunk(r, rsize);
04686         set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
04687       }
04688       else { /* exhaust dv */
04689         size_t dvs = gm->dvsize;
04690         gm->dvsize = 0;
04691         gm->dv = 0;
04692         set_inuse_and_pinuse(gm, p, dvs);
04693       }
04694       mem = chunk2mem(p);
04695       check_malloced_chunk(gm, mem, nb);
04696       goto postaction;
04697     }
04698 
04699     else if (nb < gm->topsize) { /* Split top */
04700       size_t rsize = gm->topsize -= nb;
04701       mchunkptr p = gm->top;
04702       mchunkptr r = gm->top = chunk_plus_offset(p, nb);
04703       r->head = rsize | PINUSE_BIT;
04704       set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
04705       mem = chunk2mem(p);
04706       check_top_chunk(gm, gm->top);
04707       check_malloced_chunk(gm, mem, nb);
04708       goto postaction;
04709     }
04710 
04711     mem = sys_alloc(gm, nb);
04712 
04713   postaction:
04714     POSTACTION(gm);
04715     return mem;
04716   }
04717 
04718   return 0;
04719 }
04720 
04721 void dlfree(void* mem) {
04722   /*
04723      Consolidate freed chunks with preceeding or succeeding bordering
04724      free chunks, if they exist, and then place in a bin.  Intermixed
04725      with special cases for top, dv, mmapped chunks, and usage errors.
04726   */
04727 
04728   if (mem != 0) {
04729     mchunkptr p  = mem2chunk(mem);
04730 #if FOOTERS
04731     mstate fm = get_mstate_for(p);
04732     if (!ok_magic(fm)) {
04733       USAGE_ERROR_ACTION(fm, p);
04734       return;
04735     }
04736 #else /* FOOTERS */
04737 #define fm gm
04738 #endif /* FOOTERS */
04739     if (!PREACTION(fm)) {
04740       check_inuse_chunk(fm, p);
04741       if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
04742         size_t psize = chunksize(p);
04743         mchunkptr next = chunk_plus_offset(p, psize);
04744         if (!pinuse(p)) {
04745           size_t prevsize = p->prev_foot;
04746           if ((prevsize & IS_MMAPPED_BIT) != 0) {
04747             prevsize &= ~IS_MMAPPED_BIT;
04748             psize += prevsize + MMAP_FOOT_PAD;
04749             if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
04750               fm->footprint -= psize;
04751             goto postaction;
04752           }
04753           else {
04754             mchunkptr prev = chunk_minus_offset(p, prevsize);
04755             psize += prevsize;
04756             p = prev;
04757             if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
04758               if (p != fm->dv) {
04759                 unlink_chunk(fm, p, prevsize);
04760               }
04761               else if ((next->head & INUSE_BITS) == INUSE_BITS) {
04762                 fm->dvsize = psize;
04763                 set_free_with_pinuse(p, psize, next);
04764                 goto postaction;
04765               }
04766             }
04767             else
04768               goto erroraction;
04769           }
04770         }
04771 
04772         if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
04773           if (!cinuse(next)) {  /* consolidate forward */
04774             if (next == fm->top) {
04775               size_t tsize = fm->topsize += psize;
04776               fm->top = p;
04777               p->head = tsize | PINUSE_BIT;
04778               if (p == fm->dv) {
04779                 fm->dv = 0;
04780                 fm->dvsize = 0;
04781               }
04782               if (should_trim(fm, tsize))
04783                 sys_trim(fm, 0);
04784               goto postaction;
04785             }
04786             else if (next == fm->dv) {
04787               size_t dsize = fm->dvsize += psize;
04788               fm->dv = p;
04789               set_size_and_pinuse_of_free_chunk(p, dsize);
04790               goto postaction;
04791             }
04792             else {
04793               size_t nsize = chunksize(next);
04794               psize += nsize;
04795               unlink_chunk(fm, next, nsize);
04796               set_size_and_pinuse_of_free_chunk(p, psize);
04797               if (p == fm->dv) {
04798                 fm->dvsize = psize;
04799                 goto postaction;
04800               }
04801             }
04802           }
04803           else
04804             set_free_with_pinuse(p, psize, next);
04805 
04806           if (is_small(psize)) {
04807             insert_small_chunk(fm, p, psize);
04808             check_free_chunk(fm, p);
04809           }
04810           else {
04811             tchunkptr tp = (tchunkptr)p;
04812             insert_large_chunk(fm, tp, psize);
04813             check_free_chunk(fm, p);
04814             if (--fm->release_checks == 0)
04815               release_unused_segments(fm);
04816           }
04817           goto postaction;
04818         }
04819       }
04820     erroraction:
04821       USAGE_ERROR_ACTION(fm, p);
04822     postaction:
04823       POSTACTION(fm);
04824     }
04825   }
04826 #if !FOOTERS
04827 #undef fm
04828 #endif /* FOOTERS */
04829 }
04830 
04831 void* dlcalloc(size_t n_elements, size_t elem_size) {
04832   void* mem;
04833   size_t req = 0;
04834   if (n_elements != 0) {
04835     req = n_elements * elem_size;
04836     if (((n_elements | elem_size) & ~(size_t)0xffff) &&
04837         (req / n_elements != elem_size))
04838       req = MAX_SIZE_T; /* force downstream failure on overflow */
04839   }
04840   mem = dlmalloc(req);
04841   if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
04842     memset(mem, 0, req);
04843   return mem;
04844 }
04845 
04846 void* dlrealloc(void* oldmem, size_t bytes) {
04847   if (oldmem == 0)
04848     return dlmalloc(bytes);
04849 #ifdef REALLOC_ZERO_BYTES_FREES
04850   if (bytes == 0) {
04851     dlfree(oldmem);
04852     return 0;
04853   }
04854 #endif /* REALLOC_ZERO_BYTES_FREES */
04855   else {
04856 #if ! FOOTERS
04857     mstate m = gm;
04858 #else /* FOOTERS */
04859     mstate m = get_mstate_for(mem2chunk(oldmem));
04860     if (!ok_magic(m)) {
04861       USAGE_ERROR_ACTION(m, oldmem);
04862       return 0;
04863     }
04864 #endif /* FOOTERS */
04865     return internal_realloc(m, oldmem, bytes);
04866   }
04867 }
04868 
04869 void* dlmemalign(size_t alignment, size_t bytes) {
04870   return internal_memalign(gm, alignment, bytes);
04871 }
04872 
04873 void** dlindependent_calloc(size_t n_elements, size_t elem_size,
04874                                  void* chunks[]) {
04875   size_t sz = elem_size; /* serves as 1-element array */
04876   return ialloc(gm, n_elements, &sz, 3, chunks);
04877 }
04878 
04879 void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
04880                                    void* chunks[]) {
04881   return ialloc(gm, n_elements, sizes, 0, chunks);
04882 }
04883 
04884 void* dlvalloc(size_t bytes) {
04885   size_t pagesz;
04886   ensure_initialization();
04887   pagesz = mparams.page_size;
04888   return dlmemalign(pagesz, bytes);
04889 }
04890 
04891 void* dlpvalloc(size_t bytes) {
04892   size_t pagesz;
04893   ensure_initialization();
04894   pagesz = mparams.page_size;
04895   return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
04896 }
04897 
04898 int dlmalloc_trim(size_t pad) {
04899   ensure_initialization();
04900   int result = 0;
04901   if (!PREACTION(gm)) {
04902     result = sys_trim(gm, pad);
04903     POSTACTION(gm);
04904   }
04905   return result;
04906 }
04907 
04908 size_t dlmalloc_footprint(void) {
04909   return gm->footprint;
04910 }
04911 
04912 size_t dlmalloc_max_footprint(void) {
04913   return gm->max_footprint;
04914 }
04915 
04916 #if !NO_MALLINFO
04917 struct mallinfo dlmallinfo(void) {
04918   return internal_mallinfo(gm);
04919 }
04920 #endif /* NO_MALLINFO */
04921 
04922 void dlmalloc_stats() {
04923   internal_malloc_stats(gm);
04924 }
04925 
04926 int dlmallopt(int param_number, int value) {
04927   return change_mparam(param_number, value);
04928 }
04929 
04930 #endif /* !ONLY_MSPACES */
04931 
04932 size_t dlmalloc_usable_size(void* mem) {
04933   if (mem != 0) {
04934     mchunkptr p = mem2chunk(mem);
04935     if (cinuse(p))
04936       return chunksize(p) - overhead_for(p);
04937   }
04938   return 0;
04939 }
04940 
04941 /* ----------------------------- user mspaces ---------------------------- */
04942 
04943 #if MSPACES
04944 
04945 static mstate init_user_mstate(char* tbase, size_t tsize) {
04946   size_t msize = pad_request(sizeof(struct malloc_state));
04947   mchunkptr mn;
04948   mchunkptr msp = align_as_chunk(tbase);
04949   mstate m = (mstate)(chunk2mem(msp));
04950   memset(m, 0, msize);
04951   INITIAL_LOCK(&m->mutex);
04952   msp->head = (msize|PINUSE_BIT|CINUSE_BIT);
04953   m->seg.base = m->least_addr = tbase;
04954   m->seg.size = m->footprint = m->max_footprint = tsize;
04955   m->magic = mparams.magic;
04956   m->release_checks = MAX_RELEASE_CHECK_RATE;
04957   m->mflags = mparams.default_mflags;
04958   m->extp = 0;
04959   m->exts = 0;
04960   disable_contiguous(m);
04961   init_bins(m);
04962   mn = next_chunk(mem2chunk(m));
04963   init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
04964   check_top_chunk(m, m->top);
04965   return m;
04966 }
04967 
04968 mspace create_mspace(size_t capacity, int locked) {
04969   mstate m = 0;
04970   size_t msize;
04971   ensure_initialization();
04972   msize = pad_request(sizeof(struct malloc_state));
04973   if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
04974     size_t rs = ((capacity == 0)? mparams.granularity :
04975                  (capacity + TOP_FOOT_SIZE + msize));
04976     size_t tsize = granularity_align(rs);
04977     char* tbase = (char*)(CALL_MMAP(tsize));
04978     if (tbase != CMFAIL) {
04979       m = init_user_mstate(tbase, tsize);
04980       m->seg.sflags = IS_MMAPPED_BIT;
04981       set_lock(m, locked);
04982     }
04983   }
04984   return (mspace)m;
04985 }
04986 
04987 mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
04988   mstate m = 0;
04989   size_t msize;
04990   ensure_initialization();
04991   msize = pad_request(sizeof(struct malloc_state));
04992   if (capacity > msize + TOP_FOOT_SIZE &&
04993       capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
04994     m = init_user_mstate((char*)base, capacity);
04995     m->seg.sflags = EXTERN_BIT;
04996     set_lock(m, locked);
04997   }
04998   return (mspace)m;
04999 }
05000 
05001 int mspace_mmap_large_chunks(mspace msp, int enable) {
05002   int ret = 0;
05003   mstate ms = (mstate)msp;
05004   if (!PREACTION(ms)) {
05005     if (use_mmap(ms))
05006       ret = 1;
05007     if (enable)
05008       enable_mmap(ms);
05009     else
05010       disable_mmap(ms);
05011     POSTACTION(ms);
05012   }
05013   return ret;
05014 }
05015 
05016 size_t destroy_mspace(mspace msp) {
05017   size_t freed = 0;
05018   mstate ms = (mstate)msp;
05019   if (ok_magic(ms)) {
05020     msegmentptr sp = &ms->seg;
05021     while (sp != 0) {
05022       char* base = sp->base;
05023       size_t size = sp->size;
05024       flag_t flag = sp->sflags;
05025       sp = sp->next;
05026       if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) &&
05027           CALL_MUNMAP(base, size) == 0)
05028         freed += size;
05029     }
05030   }
05031   else {
05032     USAGE_ERROR_ACTION(ms,ms);
05033   }
05034   return freed;
05035 }
05036 
05037 /*
05038   mspace versions of routines are near-clones of the global
05039   versions. This is not so nice but better than the alternatives.
05040 */
05041 
05042 
05043 void* mspace_malloc(mspace msp, size_t bytes) {
05044   mstate ms = (mstate)msp;
05045   if (!ok_magic(ms)) {
05046     USAGE_ERROR_ACTION(ms,ms);
05047     return 0;
05048   }
05049   if (!PREACTION(ms)) {
05050     void* mem;
05051     size_t nb;
05052     if (bytes <= MAX_SMALL_REQUEST) {
05053       bindex_t idx;
05054       binmap_t smallbits;
05055       nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
05056       idx = small_index(nb);
05057       smallbits = ms->smallmap >> idx;
05058 
05059       if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
05060         mchunkptr b, p;
05061         idx += ~smallbits & 1;       /* Uses next bin if idx empty */
05062         b = smallbin_at(ms, idx);
05063         p = b->fd;
05064         assert(chunksize(p) == small_index2size(idx));
05065         unlink_first_small_chunk(ms, b, p, idx);
05066         set_inuse_and_pinuse(ms, p, small_index2size(idx));
05067         mem = chunk2mem(p);
05068         check_malloced_chunk(ms, mem, nb);
05069         goto postaction;
05070       }
05071 
05072       else if (nb > ms->dvsize) {
05073         if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
05074           mchunkptr b, p, r;
05075           size_t rsize;
05076           bindex_t i;
05077           binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
05078           binmap_t leastbit = least_bit(leftbits);
05079           compute_bit2idx(leastbit, i);
05080           b = smallbin_at(ms, i);
05081           p = b->fd;
05082           assert(chunksize(p) == small_index2size(i));
05083           unlink_first_small_chunk(ms, b, p, i);
05084           rsize = small_index2size(i) - nb;
05085           /* Fit here cannot be remainderless if 4byte sizes */
05086           if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
05087             set_inuse_and_pinuse(ms, p, small_index2size(i));
05088           else {
05089             set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
05090             r = chunk_plus_offset(p, nb);
05091             set_size_and_pinuse_of_free_chunk(r, rsize);
05092             replace_dv(ms, r, rsize);
05093           }
05094           mem = chunk2mem(p);
05095           check_malloced_chunk(ms, mem, nb);
05096           goto postaction;
05097         }
05098 
05099         else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
05100           check_malloced_chunk(ms, mem, nb);
05101           goto postaction;
05102         }
05103       }
05104     }
05105     else if (bytes >= MAX_REQUEST)
05106       nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
05107     else {
05108       nb = pad_request(bytes);
05109       if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
05110         check_malloced_chunk(ms, mem, nb);
05111         goto postaction;
05112       }
05113     }
05114 
05115     if (nb <= ms->dvsize) {
05116       size_t rsize = ms->dvsize - nb;
05117       mchunkptr p = ms->dv;
05118       if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
05119         mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
05120         ms->dvsize = rsize;
05121         set_size_and_pinuse_of_free_chunk(r, rsize);
05122         set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
05123       }
05124       else { /* exhaust dv */
05125         size_t dvs = ms->dvsize;
05126         ms->dvsize = 0;
05127         ms->dv = 0;
05128         set_inuse_and_pinuse(ms, p, dvs);
05129       }
05130       mem = chunk2mem(p);
05131       check_malloced_chunk(ms, mem, nb);
05132       goto postaction;
05133     }
05134 
05135     else if (nb < ms->topsize) { /* Split top */
05136       size_t rsize = ms->topsize -= nb;
05137       mchunkptr p = ms->top;
05138       mchunkptr r = ms->top = chunk_plus_offset(p, nb);
05139       r->head = rsize | PINUSE_BIT;
05140       set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
05141       mem = chunk2mem(p);
05142       check_top_chunk(ms, ms->top);
05143       check_malloced_chunk(ms, mem, nb);
05144       goto postaction;
05145     }
05146 
05147     mem = sys_alloc(ms, nb);
05148 
05149   postaction:
05150     POSTACTION(ms);
05151     return mem;
05152   }
05153 
05154   return 0;
05155 }
05156 
05157 void mspace_free(mspace msp, void* mem) {
05158   if (mem != 0) {
05159     mchunkptr p  = mem2chunk(mem);
05160 #if FOOTERS
05161     mstate fm = get_mstate_for(p);
05162 #else /* FOOTERS */
05163     mstate fm = (mstate)msp;
05164 #endif /* FOOTERS */
05165     if (!ok_magic(fm)) {
05166       USAGE_ERROR_ACTION(fm, p);
05167       return;
05168     }
05169     if (!PREACTION(fm)) {
05170       check_inuse_chunk(fm, p);
05171       if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
05172         size_t psize = chunksize(p);
05173         mchunkptr next = chunk_plus_offset(p, psize);
05174         if (!pinuse(p)) {
05175           size_t prevsize = p->prev_foot;
05176           if ((prevsize & IS_MMAPPED_BIT) != 0) {
05177             prevsize &= ~IS_MMAPPED_BIT;
05178             psize += prevsize + MMAP_FOOT_PAD;
05179             if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
05180               fm->footprint -= psize;
05181             goto postaction;
05182           }
05183           else {
05184             mchunkptr prev = chunk_minus_offset(p, prevsize);
05185             psize += prevsize;
05186             p = prev;
05187             if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
05188               if (p != fm->dv) {
05189                 unlink_chunk(fm, p, prevsize);
05190               }
05191               else if ((next->head & INUSE_BITS) == INUSE_BITS) {
05192                 fm->dvsize = psize;
05193                 set_free_with_pinuse(p, psize, next);
05194                 goto postaction;
05195               }
05196             }
05197             else
05198               goto erroraction;
05199           }
05200         }
05201 
05202         if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
05203           if (!cinuse(next)) {  /* consolidate forward */
05204             if (next == fm->top) {
05205               size_t tsize = fm->topsize += psize;
05206               fm->top = p;
05207               p->head = tsize | PINUSE_BIT;
05208               if (p == fm->dv) {
05209                 fm->dv = 0;
05210                 fm->dvsize = 0;
05211               }
05212               if (should_trim(fm, tsize))
05213                 sys_trim(fm, 0);
05214               goto postaction;
05215             }
05216             else if (next == fm->dv) {
05217               size_t dsize = fm->dvsize += psize;
05218               fm->dv = p;
05219               set_size_and_pinuse_of_free_chunk(p, dsize);
05220               goto postaction;
05221             }
05222             else {
05223               size_t nsize = chunksize(next);
05224               psize += nsize;
05225               unlink_chunk(fm, next, nsize);
05226               set_size_and_pinuse_of_free_chunk(p, psize);
05227               if (p == fm->dv) {
05228                 fm->dvsize = psize;
05229                 goto postaction;
05230               }
05231             }
05232           }
05233           else
05234             set_free_with_pinuse(p, psize, next);
05235 
05236           if (is_small(psize)) {
05237             insert_small_chunk(fm, p, psize);
05238             check_free_chunk(fm, p);
05239           }
05240           else {
05241             tchunkptr tp = (tchunkptr)p;
05242             insert_large_chunk(fm, tp, psize);
05243             check_free_chunk(fm, p);
05244             if (--fm->release_checks == 0)
05245               release_unused_segments(fm);
05246           }
05247           goto postaction;
05248         }
05249       }
05250     erroraction:
05251       USAGE_ERROR_ACTION(fm, p);
05252     postaction:
05253       POSTACTION(fm);
05254     }
05255   }
05256 }
05257 
05258 void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
05259   void* mem;
05260   size_t req = 0;
05261   mstate ms = (mstate)msp;
05262   if (!ok_magic(ms)) {
05263     USAGE_ERROR_ACTION(ms,ms);
05264     return 0;
05265   }
05266   if (n_elements != 0) {
05267     req = n_elements * elem_size;
05268     if (((n_elements | elem_size) & ~(size_t)0xffff) &&
05269         (req / n_elements != elem_size))
05270       req = MAX_SIZE_T; /* force downstream failure on overflow */
05271   }
05272   mem = internal_malloc(ms, req);
05273   if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
05274     memset(mem, 0, req);
05275   return mem;
05276 }
05277 
05278 void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
05279   if (oldmem == 0)
05280     return mspace_malloc(msp, bytes);
05281 #ifdef REALLOC_ZERO_BYTES_FREES
05282   if (bytes == 0) {
05283     mspace_free(msp, oldmem);
05284     return 0;
05285   }
05286 #endif /* REALLOC_ZERO_BYTES_FREES */
05287   else {
05288 #if FOOTERS
05289     mchunkptr p  = mem2chunk(oldmem);
05290     mstate ms = get_mstate_for(p);
05291 #else /* FOOTERS */
05292     mstate ms = (mstate)msp;
05293 #endif /* FOOTERS */
05294     if (!ok_magic(ms)) {
05295       USAGE_ERROR_ACTION(ms,ms);
05296       return 0;
05297     }
05298     return internal_realloc(ms, oldmem, bytes);
05299   }
05300 }
05301 
05302 void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
05303   mstate ms = (mstate)msp;
05304   if (!ok_magic(ms)) {
05305     USAGE_ERROR_ACTION(ms,ms);
05306     return 0;
05307   }
05308   return internal_memalign(ms, alignment, bytes);
05309 }
05310 
05311 void** mspace_independent_calloc(mspace msp, size_t n_elements,
05312                                  size_t elem_size, void* chunks[]) {
05313   size_t sz = elem_size; /* serves as 1-element array */
05314   mstate ms = (mstate)msp;
05315   if (!ok_magic(ms)) {
05316     USAGE_ERROR_ACTION(ms,ms);
05317     return 0;
05318   }
05319   return ialloc(ms, n_elements, &sz, 3, chunks);
05320 }
05321 
05322 void** mspace_independent_comalloc(mspace msp, size_t n_elements,
05323                                    size_t sizes[], void* chunks[]) {
05324   mstate ms = (mstate)msp;
05325   if (!ok_magic(ms)) {
05326     USAGE_ERROR_ACTION(ms,ms);
05327     return 0;
05328   }
05329   return ialloc(ms, n_elements, sizes, 0, chunks);
05330 }
05331 
05332 int mspace_trim(mspace msp, size_t pad) {
05333   int result = 0;
05334   mstate ms = (mstate)msp;
05335   if (ok_magic(ms)) {
05336     if (!PREACTION(ms)) {
05337       result = sys_trim(ms, pad);
05338       POSTACTION(ms);
05339     }
05340   }
05341   else {
05342     USAGE_ERROR_ACTION(ms,ms);
05343   }
05344   return result;
05345 }
05346 
05347 void mspace_malloc_stats(mspace msp) {
05348   mstate ms = (mstate)msp;
05349   if (ok_magic(ms)) {
05350     internal_malloc_stats(ms);
05351   }
05352   else {
05353     USAGE_ERROR_ACTION(ms,ms);
05354   }
05355 }
05356 
05357 size_t mspace_footprint(mspace msp) {
05358   size_t result = 0;
05359   mstate ms = (mstate)msp;
05360   if (ok_magic(ms)) {
05361     result = ms->footprint;
05362   }
05363   else {
05364     USAGE_ERROR_ACTION(ms,ms);
05365   }
05366   return result;
05367 }
05368 
05369 
05370 size_t mspace_max_footprint(mspace msp) {
05371   size_t result = 0;
05372   mstate ms = (mstate)msp;
05373   if (ok_magic(ms)) {
05374     result = ms->max_footprint;
05375   }
05376   else {
05377     USAGE_ERROR_ACTION(ms,ms);
05378   }
05379   return result;
05380 }
05381 
05382 
05383 #if !NO_MALLINFO
05384 struct mallinfo mspace_mallinfo(mspace msp) {
05385   mstate ms = (mstate)msp;
05386   if (!ok_magic(ms)) {
05387     USAGE_ERROR_ACTION(ms,ms);
05388   }
05389   return internal_mallinfo(ms);
05390 }
05391 #endif /* NO_MALLINFO */
05392 
05393 size_t mspace_usable_size(void* mem) {
05394   if (mem != 0) {
05395     mchunkptr p = mem2chunk(mem);
05396     if (cinuse(p))
05397       return chunksize(p) - overhead_for(p);
05398   }
05399   return 0;
05400 }
05401 
05402 int mspace_mallopt(int param_number, int value) {
05403   return change_mparam(param_number, value);
05404 }
05405 
05406 #endif /* MSPACES */
05407 
05408 /* -------------------- Alternative MORECORE functions ------------------- */
05409 
05410 /*
05411   Guidelines for creating a custom version of MORECORE:
05412 
05413   * For best performance, MORECORE should allocate in multiples of pagesize.
05414   * MORECORE may allocate more memory than requested. (Or even less,
05415       but this will usually result in a malloc failure.)
05416   * MORECORE must not allocate memory when given argument zero, but
05417       instead return one past the end address of memory from previous
05418       nonzero call.
05419   * For best performance, consecutive calls to MORECORE with positive
05420       arguments should return increasing addresses, indicating that
05421       space has been contiguously extended.
05422   * Even though consecutive calls to MORECORE need not return contiguous
05423       addresses, it must be OK for malloc'ed chunks to span multiple
05424       regions in those cases where they do happen to be contiguous.
05425   * MORECORE need not handle negative arguments -- it may instead
05426       just return MFAIL when given negative arguments.
05427       Negative arguments are always multiples of pagesize. MORECORE
05428       must not misinterpret negative args as large positive unsigned
05429       args. You can suppress all such calls from even occurring by defining
05430       MORECORE_CANNOT_TRIM,
05431 
05432   As an example alternative MORECORE, here is a custom allocator
05433   kindly contributed for pre-OSX macOS.  It uses virtually but not
05434   necessarily physically contiguous non-paged memory (locked in,
05435   present and won't get swapped out).  You can use it by uncommenting
05436   this section, adding some #includes, and setting up the appropriate
05437   defines above:
05438 
05439       #define MORECORE osMoreCore
05440 
05441   There is also a shutdown routine that should somehow be called for
05442   cleanup upon program exit.
05443 
05444   #define MAX_POOL_ENTRIES 100
05445   #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
05446   static int next_os_pool;
05447   void *our_os_pools[MAX_POOL_ENTRIES];
05448 
05449   void *osMoreCore(int size)
05450   {
05451     void *ptr = 0;
05452     static void *sbrk_top = 0;
05453 
05454     if (size > 0)
05455     {
05456       if (size < MINIMUM_MORECORE_SIZE)
05457          size = MINIMUM_MORECORE_SIZE;
05458       if (CurrentExecutionLevel() == kTaskLevel)
05459          ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
05460       if (ptr == 0)
05461       {
05462         return (void *) MFAIL;
05463       }
05464       // save ptrs so they can be freed during cleanup
05465       our_os_pools[next_os_pool] = ptr;
05466       next_os_pool++;
05467       ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
05468       sbrk_top = (char *) ptr + size;
05469       return ptr;
05470     }
05471     else if (size < 0)
05472     {
05473       // we don't currently support shrink behavior
05474       return (void *) MFAIL;
05475     }
05476     else
05477     {
05478       return sbrk_top;
05479     }
05480   }
05481 
05482   // cleanup any allocated memory pools
05483   // called as last thing before shutting down driver
05484 
05485   void osCleanupMem(void)
05486   {
05487     void **ptr;
05488 
05489     for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
05490       if (*ptr)
05491       {
05492          PoolDeallocate(*ptr);
05493          *ptr = 0;
05494       }
05495   }
05496 
05497 */
05498 
05499 
05500 /* -----------------------------------------------------------------------
05501 History:
05502     V2.8.4 (not yet released)
05503       * Add mspace_mmap_large_chunks; thanks to Jean Brouwers
05504       * Fix insufficient sys_alloc padding when using 16byte alignment
05505       * Fix bad error check in mspace_footprint
05506       * Adaptations for ptmalloc, courtesy of Wolfram Gloger.
05507       * Reentrant spin locks, courtesy of Earl Chew and others
05508       * Win32 improvements, courtesy of Niall Douglas and Earl Chew
05509       * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options
05510       * Extension hook in malloc_state
05511       * Various small adjustments to reduce warnings on some compilers
05512       * Various configuration extensions/changes for more platforms. Thanks
05513          to all who contributed these.
05514 
05515     V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
05516       * Add max_footprint functions
05517       * Ensure all appropriate literals are size_t
05518       * Fix conditional compilation problem for some #define settings
05519       * Avoid concatenating segments with the one provided
05520         in create_mspace_with_base
05521       * Rename some variables to avoid compiler shadowing warnings
05522       * Use explicit lock initialization.
05523       * Better handling of sbrk interference.
05524       * Simplify and fix segment insertion, trimming and mspace_destroy
05525       * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
05526       * Thanks especially to Dennis Flanagan for help on these.
05527 
05528     V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
05529       * Fix memalign brace error.
05530 
05531     V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
05532       * Fix improper #endif nesting in C++
05533       * Add explicit casts needed for C++
05534 
05535     V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
05536       * Use trees for large bins
05537       * Support mspaces
05538       * Use segments to unify sbrk-based and mmap-based system allocation,
05539         removing need for emulation on most platforms without sbrk.
05540       * Default safety checks
05541       * Optional footer checks. Thanks to William Robertson for the idea.
05542       * Internal code refactoring
05543       * Incorporate suggestions and platform-specific changes.
05544         Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
05545         Aaron Bachmann,  Emery Berger, and others.
05546       * Speed up non-fastbin processing enough to remove fastbins.
05547       * Remove useless cfree() to avoid conflicts with other apps.
05548       * Remove internal memcpy, memset. Compilers handle builtins better.
05549       * Remove some options that no one ever used and rename others.
05550 
05551     V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
05552       * Fix malloc_state bitmap array misdeclaration
05553 
05554     V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
05555       * Allow tuning of FIRST_SORTED_BIN_SIZE
05556       * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
05557       * Better detection and support for non-contiguousness of MORECORE.
05558         Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
05559       * Bypass most of malloc if no frees. Thanks To Emery Berger.
05560       * Fix freeing of old top non-contiguous chunk im sysmalloc.
05561       * Raised default trim and map thresholds to 256K.
05562       * Fix mmap-related #defines. Thanks to Lubos Lunak.
05563       * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
05564       * Branch-free bin calculation
05565       * Default trim and mmap thresholds now 256K.
05566 
05567     V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
05568       * Introduce independent_comalloc and independent_calloc.
05569         Thanks to Michael Pachos for motivation and help.
05570       * Make optional .h file available
05571       * Allow > 2GB requests on 32bit systems.
05572       * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
05573         Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
05574         and Anonymous.
05575       * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
05576         helping test this.)
05577       * memalign: check alignment arg
05578       * realloc: don't try to shift chunks backwards, since this
05579         leads to  more fragmentation in some programs and doesn't
05580         seem to help in any others.
05581       * Collect all cases in malloc requiring system memory into sysmalloc
05582       * Use mmap as backup to sbrk
05583       * Place all internal state in malloc_state
05584       * Introduce fastbins (although similar to 2.5.1)
05585       * Many minor tunings and cosmetic improvements
05586       * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
05587       * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
05588         Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
05589       * Include errno.h to support default failure action.
05590 
05591     V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
05592       * return null for negative arguments
05593       * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
05594          * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
05595           (e.g. WIN32 platforms)
05596          * Cleanup header file inclusion for WIN32 platforms
05597          * Cleanup code to avoid Microsoft Visual C++ compiler complaints
05598          * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
05599            memory allocation routines
05600          * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
05601          * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
05602            usage of 'assert' in non-WIN32 code
05603          * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
05604            avoid infinite loop
05605       * Always call 'fREe()' rather than 'free()'
05606 
05607     V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
05608       * Fixed ordering problem with boundary-stamping
05609 
05610     V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
05611       * Added pvalloc, as recommended by H.J. Liu
05612       * Added 64bit pointer support mainly from Wolfram Gloger
05613       * Added anonymously donated WIN32 sbrk emulation
05614       * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
05615       * malloc_extend_top: fix mask error that caused wastage after
05616         foreign sbrks
05617       * Add linux mremap support code from HJ Liu
05618 
05619     V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
05620       * Integrated most documentation with the code.
05621       * Add support for mmap, with help from
05622         Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
05623       * Use last_remainder in more cases.
05624       * Pack bins using idea from  colin@nyx10.cs.du.edu
05625       * Use ordered bins instead of best-fit threshhold
05626       * Eliminate block-local decls to simplify tracing and debugging.
05627       * Support another case of realloc via move into top
05628       * Fix error occuring when initial sbrk_base not word-aligned.
05629       * Rely on page size for units instead of SBRK_UNIT to
05630         avoid surprises about sbrk alignment conventions.
05631       * Add mallinfo, mallopt. Thanks to Raymond Nijssen
05632         (raymond@es.ele.tue.nl) for the suggestion.
05633       * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
05634       * More precautions for cases where other routines call sbrk,
05635         courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
05636       * Added macros etc., allowing use in linux libc from
05637         H.J. Lu (hjl@gnu.ai.mit.edu)
05638       * Inverted this history list
05639 
05640     V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
05641       * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
05642       * Removed all preallocation code since under current scheme
05643         the work required to undo bad preallocations exceeds
05644         the work saved in good cases for most test programs.
05645       * No longer use return list or unconsolidated bins since
05646         no scheme using them consistently outperforms those that don't
05647         given above changes.
05648       * Use best fit for very large chunks to prevent some worst-cases.
05649       * Added some support for debugging
05650 
05651     V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
05652       * Removed footers when chunks are in use. Thanks to
05653         Paul Wilson (wilson@cs.texas.edu) for the suggestion.
05654 
05655     V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
05656       * Added malloc_trim, with help from Wolfram Gloger
05657         (wmglo@Dent.MED.Uni-Muenchen.DE).
05658 
05659     V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
05660 
05661     V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
05662       * realloc: try to expand in both directions
05663       * malloc: swap order of clean-bin strategy;
05664       * realloc: only conditionally expand backwards
05665       * Try not to scavenge used bins
05666       * Use bin counts as a guide to preallocation
05667       * Occasionally bin return list chunks in first scan
05668       * Add a few optimizations from colin@nyx10.cs.du.edu
05669 
05670     V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
05671       * faster bin computation & slightly different binning
05672       * merged all consolidations to one part of malloc proper
05673          (eliminating old malloc_find_space & malloc_clean_bin)
05674       * Scan 2 returns chunks (not just 1)
05675       * Propagate failure in realloc if malloc returns 0
05676       * Add stuff to allow compilation on non-ANSI compilers
05677           from kpv@research.att.com
05678 
05679     V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
05680       * removed potential for odd address access in prev_chunk
05681       * removed dependency on getpagesize.h
05682       * misc cosmetics and a bit more internal documentation
05683       * anticosmetics: mangled names in macros to evade debugger strangeness
05684       * tested on sparc, hp-700, dec-mips, rs6000
05685           with gcc & native cc (hp, dec only) allowing
05686           Detlefs & Zorn comparison study (in SIGPLAN Notices.)
05687 
05688     Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
05689       * Based loosely on libg++-1.2X malloc. (It retains some of the overall
05690          structure of old version,  but most details differ.)
05691 
05692 */
05693 
05694 

Generated on Wed Feb 8 06:00:12 2012 for cpp by  doxygen 1.5.6