sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_malloc.c (196611B)


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