malloc.c

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

Generated by doxygen 1.7.1 on Sun Feb 19 2012 01:02:16 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs