19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL - Simple DirectMedia Layer 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Copyright (C) 1997-2012 Sam Lantinga 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is free software; you can redistribute it and/or 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall modify it under the terms of the GNU Lesser General Public 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License as published by the Free Software Foundation; either 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall version 2.1 of the License, or (at your option) any later version. 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is distributed in the hope that it will be useful, 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but WITHOUT ANY WARRANTY; without even the implied warranty of 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Lesser General Public License for more details. 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You should have received a copy of the GNU Lesser General Public 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License along with this library; if not, write to the Free Software 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Sam Lantinga 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall slouken@libsdl.org 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_config.h" 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* This file contains portable memory management functions for SDL */ 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_stdinc.h" 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_MALLOC 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_SYS_TYPES_H 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STDIO_H 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STRINGS_H 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STRING_H 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STDLIB_H 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ABORT 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is a version (aka dlmalloc) of malloc/free/realloc written by 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Doug Lea and released to the public domain, as explained at 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall http://creativecommons.org/licenses/publicdomain. Send questions, 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall comments, complaints, performance data, etc to dl@cs.oswego.edu 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall* Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Note: There may be an updated version of this malloc obtainable at 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ftp://gee.cs.oswego.edu/pub/misc/malloc.c 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Check before installing! 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall* Quickstart 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is all in one file to simplify the most common usage: 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ftp it, compile it (-O3), and link it into another program. All of 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the compile-time options default to reasonable values for use on 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall most platforms. You might later want to step through various 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compile-time and dynamic tuning options. 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall For convenience, an include file for code using this malloc is at: 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You don't really need this .h file unless you call functions not 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall defined in your system include files. The .h file contains only the 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall excerpts from this file needed for using this malloc on ANSI C/C++ 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall systems, so long as you haven't changed compile-time options about 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall naming and tuning parameters. If you do, then you can create your 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall own malloc.h that does include all settings by cutting at the point 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall indicated below. Note that you may already by default be using a C 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall library containing a malloc that is based on some version of this 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc (for example in linux). You might still want to use the one 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in this file to customize settings or to avoid overheads associated 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with library versions. 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall* Vital statistics: 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Supported pointer/size_t representation: 4 or 8 bytes 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t MUST be an unsigned type of the same width as 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointers. (If you are using an ancient system that declares 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t as a signed type, or need it to be a different width 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall than pointers, you can use a previous release of this malloc 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (e.g. 2.7.2) supporting these.) 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Alignment: 8 bytes (default) 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This suffices for nearly all current machines and C compilers. 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall However, you can define MALLOC_ALIGNMENT to be wider than this 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if necessary (up to 128bytes), at the expense of using more space. 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8 or 16 bytes (if 8byte sizes) 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each malloced chunk has a hidden word of overhead holding size 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and status information, and additional cross-check word 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if FOOTERS is defined. 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8-byte ptrs: 32 bytes (including overhead) 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Even a request for zero bytes (i.e., malloc(0)) returns a 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointer to something of the minimum allocatable size. 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The maximum overhead wastage (i.e., number of extra bytes 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocated than were requested in malloc) is less than or equal 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to the minimum size, except for requests >= mmap_threshold that 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are serviced via mmap(), where the worst case wastage is about 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32 bytes plus the remainder from a system page (the minimal 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mmap unit); typically 4096 or 8192 bytes. 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Security: static-safe; optionally more or less 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The "security" of malloc refers to the ability of malicious 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall code to accentuate the effects of errors (for example, freeing 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space that is not currently malloc'ed or overwriting past the 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ends of chunks) in code that calls malloc. This malloc 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall guarantees not to modify any memory locations below the base of 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall heap, i.e., static variables, even in the presence of usage 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall errors. The routines additionally detect most improper frees 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and reallocs. All this holds as long as the static bookkeeping 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for malloc itself is not corrupted by some other means. This 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is only one aspect of security -- these checks do not, and 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cannot, detect all possible programming errors. 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If FOOTERS is defined nonzero, then each allocated chunk 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall carries an additional check word to verify that it was malloced 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall from its space. These check words are the same within each 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall execution of a program using malloc, but differ across 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall executions, so externally crafted fake chunks cannot be 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freed. This improves security by rejecting frees/reallocs that 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall could corrupt heap memory, in addition to the checks preventing 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writes to statics that are always on. This may further improve 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall security at the expense of time and space overhead. (Note that 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall FOOTERS may also be worth using with MSPACES.) 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall By default detected errors cause the program to abort (calling 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "abort()"). You can override this to instead proceed past 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall errors by defining PROCEED_ON_ERROR. In this case, a bad free 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall has no effect, and a malloc that encounters a bad address 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall caused by user overwrites will ignore the bad address by 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dropping pointers and indices to all known memory. This may 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be appropriate for programs that should continue if at all 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall possible in the face of programming errors, although they may 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall run out of memory because dropped memory is never reclaimed. 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If you don't like either of these options, you can define 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else. And if if you are sure that your program using malloc has 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall no errors or vulnerabilities, you can define INSECURE to 1, 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall which might (or might not) provide a small performance improvement. 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thread-safety: NOT thread-safe unless USE_LOCKS defined 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall When USE_LOCKS is defined, each public call to malloc, free, 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall etc is surrounded with either a pthread mutex or a win32 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spinlock (depending on WIN32). This is not especially fast, and 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall can be a major bottleneck. It is designed only to provide 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall minimal protection in concurrent environments, and to provide a 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall basis for extensions. If you are using malloc in a concurrent 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall program, consider instead using ptmalloc, which is derived from 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall a version of this malloc. (See http://www.malloc.de). 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall System requirements: Any combination of MORECORE and/or MMAP/MUNMAP 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This malloc can use unix sbrk or any emulation (invoked using 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the CALL_MORECORE macro) and/or mmap/munmap or any emulation 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory. On most unix systems, it tends to work best if both 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MORECORE and MMAP are enabled. On Win32, it uses emulations 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall based on VirtualAlloc. It also uses common C library functions 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall like memset. 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Compliance: I believe it is compliant with the Single Unix Specification 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall others as well. 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall* Overview of algorithms 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is not the fastest, most space-conserving, most portable, or 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall most tunable malloc ever written. However it is among the fastest 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while also being among the most space-conserving, portable and 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tunable. Consistent balance across these factors results in a good 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall general-purpose allocator for malloc-intensive programs. 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall In most ways, this malloc is a best-fit allocator. Generally, it 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chooses the best-fitting existing chunk for a request, with ties 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall broken in approximately least-recently-used order. (This strategy 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall normally maintains low fragmentation.) However, for requests less 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall than 256bytes, it deviates from best-fit when there is not an 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exactly fitting available chunk by preferring to use space adjacent 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to that used for the previous small request, as well as by breaking 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ties in approximately most-recently-used order. (These enhance 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall locality of series of small allocations.) And for very large requests 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (>= 256Kb by default), it relies on system memory mapping 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall facilities, if supported. (This helps avoid carrying around and 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall possibly fragmenting memory used only for large chunks.) 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall All operations (except malloc_stats and mallinfo) have execution 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall times that are bounded by a constant factor of the number of bits in 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall a size_t, not counting any clearing in calloc or copying in realloc, 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall or actions surrounding MORECORE and MMAP that have times 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall proportional to the number of non-contiguous regions returned by 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system allocation routines, which is often just 1. 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The implementation is not very modular and seriously overuses 1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall macros. Perhaps someday all C compilers will do as good a job 1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall inlining modular code as can now be done by brute-force expansion, 1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but now, enough of them seem not to. 1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Some compilers issue a lot of warnings about code that is 2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dead/unreachable only on some platforms, and also about intentional 2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uses of negation on unsigned types. All known cases of each can be 2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ignored. 2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall For a longer but out of date high-level description, see 2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall http://gee.cs.oswego.edu/dl/html/malloc.html 2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall* MSPACES 2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If MSPACES is defined, then in addition to malloc, free, etc., 2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this file also defines mspace_malloc, mspace_free, etc. These 2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are versions of malloc routines that take an "mspace" argument 2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall obtained using create_mspace, to control all internal bookkeeping. 2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If ONLY_MSPACES is defined, only these versions are compiled. 2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall So if you would like to use this allocator for only some allocations, 2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and your system malloc for others, you can compile with 2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ONLY_MSPACES and then do something like... 2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static mspace mymspace = create_mspace(0,0); // for example 2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #define mymalloc(bytes) mspace_malloc(mymspace, bytes) 2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (Note: If you only need one instance of an mspace, you can instead 2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall use "USE_DL_PREFIX" to relabel the global malloc.) 2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You can similarly create thread-local allocators by storing 2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspaces as thread-locals. For example: 2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static __thread mspace tlms = 0; 2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* tlmalloc(size_t bytes) { 2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tlms == 0) tlms = create_mspace(0, 0); 2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mspace_malloc(tlms, bytes); 2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void tlfree(void* mem) { mspace_free(tlms, mem); } 2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Unless FOOTERS is defined, each mspace is completely independent. 2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You cannot allocate from one and free to another (although 2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall conformance is only weakly checked, so usage errors are not always 2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall caught). If FOOTERS is defined, then each chunk carries around a tag 2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall indicating its originating mspace, and frees are directed to their 2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall originating spaces. 2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ------------------------- Compile-time options --------------------------- 2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallBe careful in setting #define values for numerical constants of type 2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t. On some systems, literal values are not automatically extended 2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallto size_t precision unless they are explicitly casted. 2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallWIN32 default: defined if _WIN32 defined 2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Defining WIN32 sets up defaults for MS environment and compilers. 2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Otherwise defaults are for unix. 2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMALLOC_ALIGNMENT default: (size_t)8 2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Controls the minimum alignment for malloc'ed chunks. It must be a 2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall power of two and at least 8, even on machines for which smaller 2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignments would suffice. It may be defined as larger than this 2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall though. Note however that code and data structures are optimized for 2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the case of 8-byte alignment. 2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMSPACES default: 0 (false) 2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true, compile in support for independent allocation spaces. 2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is only supported if HAVE_MMAP is true. 2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallONLY_MSPACES default: 0 (false) 2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true, only compile in mspace versions, not regular versions. 2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallUSE_LOCKS default: 0 (false) 2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Causes each call to each public routine to be surrounded with 2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pthread or WIN32 mutex lock/unlock. (If set true, this can be 2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overridden on a per-mspace basis for mspace versions.) 2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallFOOTERS default: 0 2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true, provide extra checking and dispatching by placing 2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall information in the footers of allocated chunks. This adds 2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space and time overhead. 2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallINSECURE default: 0 2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true, omit checks for usage errors and heap space overwrites. 2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallUSE_DL_PREFIX default: NOT defined 2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Causes compiler to prefix all public routines with the string 'dl'. 2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This can be useful when you only want to use this malloc in one part 2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of a program, using your regular system malloc elsewhere. 2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallABORT default: defined as abort() 2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Defines how to abort on failed checks. On most systems, a failed 2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check cannot die with an "assert" or even print an informative 2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall message, because the underlying print routines in turn call malloc, 2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall which will fail again. Generally, the best policy is to simply call 2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall abort(). It's not very useful to do more than this because many 2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall errors due to overwriting will show up as address faults (null, odd 2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall addresses etc) rather than malloc-triggered checks, so will also 2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall abort. Also, most compilers know that abort() does not return, so 2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall can better optimize code conditionally calling it. 2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallPROCEED_ON_ERROR default: defined as 0 (false) 2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Controls whether detected bad addresses cause them to bypassed 2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rather than aborting. If set, detected bad arguments to free and 2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall realloc are ignored. And all bookkeeping information is zeroed out 2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall upon a detected overwrite of freed heap space, thus losing the 2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ability to ever return it from malloc again, but enabling the 2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall application to proceed. If PROCEED_ON_ERROR is defined, the 2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static variable malloc_corruption_error_count is compiled in 2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and can be examined to see if errors have occurred. This option 3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall generates slower code than the default abort policy. 3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallDEBUG default: NOT defined 3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The DEBUG setting is mainly intended for people trying to modify 3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this code or diagnose problems when porting to new platforms. 3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall However, it may also be able to better isolate user errors than just 3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using runtime checks. The assertions in the check routines spell 3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall out in more detail the assumptions and invariants underlying the 3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall algorithms. The checking is fairly extensive, and will slow down 3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall execution noticeably. Calling malloc_stats or mallinfo with DEBUG 3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set will attempt to check every non-mmapped allocated and free chunk 3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in the course of computing the summaries. 3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallABORT_ON_ASSERT_FAILURE default: defined as 1 (true) 3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Debugging assertion failures can be nearly impossible if your 3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall version of the assert macro causes malloc to be called, which will 3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lead to a cascade of further failures, blowing the runtime stack. 3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), 3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall which will usually make debugging easier. 3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The action to take before "return 0" when malloc fails to be able to 3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return memory because there is none available. 3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallHAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES 3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall True if this system supports sbrk or an emulation of it. 3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMORECORE default: sbrk 3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The name of the sbrk-style system routine to call to obtain more 3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory. See below for guidance on writing custom MORECORE 3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall functions. The type of the argument to sbrk/MORECORE varies across 3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall systems. It cannot be size_t, because it supports negative 3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall arguments, so it is normally the signed type of the same width as 3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t (sometimes declared as "intptr_t"). It doesn't much matter 3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall though. Internally, we only call it with arguments less than half 3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the max value of a size_t, which should work across all reasonable 3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall possibilities, although sometimes generating compiler warnings. See 3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall near the end of this file for guidelines for creating a custom 3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall version of MORECORE. 3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMORECORE_CONTIGUOUS default: 1 (true) 3419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true, take advantage of fact that consecutive calls to MORECORE 3429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with positive arguments always return contiguous increasing 3439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall addresses. This is true of unix sbrk. It does not hurt too much to 3449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set it true anyway, since malloc copes with non-contiguities. 3459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Setting it false when definitely non-contiguous saves time 3469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and possibly wasted space it would take to discover this though. 3479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMORECORE_CANNOT_TRIM default: NOT defined 3499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall True if MORECORE cannot release space back to the system when given 3509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall negative arguments. This is generally necessary only if you are 3519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using a hand-crafted MORECORE function that cannot handle negative 3529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall arguments. 3539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallHAVE_MMAP default: 1 (true) 3559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall True if this system supports mmap or an emulation of it. If so, and 3569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall HAVE_MORECORE is not true, MMAP is used for all system 3579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocation. If set and HAVE_MORECORE is true as well, MMAP is 3589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall primarily used to directly allocate very large blocks. It is also 3599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used as a backup strategy in cases where MORECORE fails to provide 3609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space from system. Note: A single call to MUNMAP is assumed to be 3619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall able to unmap memory that may have be allocated using multiple calls 3629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to MMAP, so long as they are adjacent. 3639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallHAVE_MREMAP default: 1 on linux, else 0 3659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If true realloc() uses mremap() to re-allocate large blocks and 3669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extend or shrink allocation spaces. 3679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMMAP_CLEARS default: 1 on unix 3699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall True if mmap clears memory so calloc doesn't need to. This is true 3709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for standard unix mmap using /dev/zero. 3719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallUSE_BUILTIN_FFS default: 0 (i.e., not used) 3739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Causes malloc to use the builtin ffs() function to compute indices. 3749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Some compilers may recognize and intrinsify ffs to be faster than the 3759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall supplied C version. Also, the case of x86 using gcc is special-cased 3769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to an asm instruction, so is already as fast as it can be, and so 3779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this setting has no effect. (On most x86s, the asm version is only 3789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall slightly faster than the C version.) 3799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallmalloc_getpagesize default: derive from system includes, or 4096. 3819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The system page size. To the extent possible, this malloc manages 3829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory from the system in page-size units. This may be (and 3839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall usually is) a function rather than a constant. This is ignored 3849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if WIN32, where page size is determined using getSystemInfo during 3859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initialization. 3869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallUSE_DEV_RANDOM default: 0 (i.e., not used) 3889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Causes malloc to use /dev/random to initialize secure magic seed for 3899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall stamping footers. Otherwise, the current time is used. 3909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallNO_MALLINFO default: 0 3929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If defined, don't compile "mallinfo". This can be a simple way 3939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of dealing with mismatches between system declarations and 3949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall those in this file. 3959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallMALLINFO_FIELD_TYPE default: size_t 3979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The type of the fields in the mallinfo struct. This was originally 3989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall defined as "int" in SVID etc, but is more usefully defined as 3999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set 4009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallREALLOC_ZERO_BYTES_FREES default: not defined 4029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This should be set if a call to realloc with zero bytes should 4039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be the same as a call to free. Some people think it should. Otherwise, 4049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall since this malloc returns a unique pointer for malloc(0), so does 4059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall realloc(p, 0). 4069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallLACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H 4089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallLACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H 4099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallLACKS_STDLIB_H default: NOT defined unless on WIN32 4109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Define these if your system does not have these header files. 4119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You might need to manually insert some of the declarations they provide. 4129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallDEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, 4149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system_info.dwAllocationGranularity in WIN32, 4159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall otherwise 64K. 4169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Also settable using mallopt(M_GRANULARITY, x) 4179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The unit for allocating and deallocating memory from the system. On 4189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall most systems with contiguous MORECORE, there is no reason to 4199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall make this more than a page. However, systems with MMAP tend to 4209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall either require or encourage larger granularities. You can increase 4219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this value to prevent system allocation functions to be called so 4229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall often, especially if they are slow. The value must be at least one 4239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall page and must be a power of two. Setting to 0 causes initialization 4249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to either page size or win32 region size. (Note: In previous 4259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall versions of malloc, the equivalent of this option was called 4269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "TOP_PAD") 4279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallDEFAULT_TRIM_THRESHOLD default: 2MB 4299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Also settable using mallopt(M_TRIM_THRESHOLD, x) 4309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The maximum amount of unused top-most memory to keep before 4319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall releasing via malloc_trim in free(). Automatic trimming is mainly 4329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall useful in long-lived programs using contiguous MORECORE. Because 4339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall trimming via sbrk can be slow on some systems, and can sometimes be 4349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall wasteful (in cases where programs immediately afterward allocate 4359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall more large chunks) the value should be high enough so that your 4369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overall system performance would improve by releasing this much 4379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory. As a rough guide, you might set to a value close to the 4389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall average size of a process (program) running on your system. 4399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Releasing this much memory would allow such a process to run in 4409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory. Generally, it is worth tuning trim thresholds when a 4419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall program undergoes phases where several large chunks are allocated 4429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and released in ways that can reuse each other's storage, perhaps 4439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mixed with phases where there are no such chunks at all. The trim 4449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value must be greater than page size to have any useful effect. To 4459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall disable trimming completely, you can set to MAX_SIZE_T. Note that the trick 4469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall some people use of mallocing a huge space and then freeing it at 4479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall program startup, in an attempt to reserve system memory, doesn't 4489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall have the intended effect under automatic trimming, since that memory 4499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall will immediately be returned to the system. 4509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallDEFAULT_MMAP_THRESHOLD default: 256K 4529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Also settable using mallopt(M_MMAP_THRESHOLD, x) 4539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The request size threshold for using MMAP to directly service a 4549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall request. Requests of at least this size that cannot be allocated 4559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using already-existing space will be serviced via mmap. (If enough 4569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall normal freed space already exists it is used instead.) Using mmap 4579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall segregates relatively large chunks of memory so that they can be 4589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall individually obtained and released from the host system. A request 4599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall serviced through mmap is never reused by any other request (at least 4609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall not directly; the system may just so happen to remap successive 4619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall requests to the same locations). Segregating space in this way has 4629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the benefits that: Mmapped space can always be individually released 4639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall back to the system, which helps keep the system level memory demands 4649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of a long-lived program low. Also, mapped memory doesn't become 4659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall `locked' between other chunks, as can happen with normally allocated 4669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks, which means that even trimming via malloc_trim would not 4679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall release them. However, it has the disadvantage that the space 4689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cannot be reclaimed, consolidated, and then used to service later 4699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall requests, as happens with normal chunks. The advantages of mmap 4709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nearly always outweigh disadvantages for "large" chunks, but the 4719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value of "large" may vary across systems. The default is an 4729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall empirically derived value that works well in most systems. You can 4739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall disable mmap by setting to MAX_SIZE_T. 4749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 4769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef WIN32 4789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef _WIN32 4799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define WIN32 1 4809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* _WIN32 */ 4819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* WIN32 */ 4829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef WIN32 4839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define WIN32_LEAN_AND_MEAN 4849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <windows.h> 4859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MMAP 1 4869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MORECORE 0 4879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_UNISTD_H 4889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_SYS_PARAM_H 4899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_SYS_MMAN_H 4909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STRING_H 4919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_STRINGS_H 4929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_SYS_TYPES_H 4939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_ERRNO_H 4949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define LACKS_FCNTL_H 4959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MALLOC_FAILURE_ACTION 4969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ 4979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* WIN32 */ 4989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(DARWIN) || defined(_DARWIN) 5009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ 5019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_MORECORE 5029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MORECORE 0 5039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MMAP 1 5049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 5059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DARWIN */ 5069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_SYS_TYPES_H 5089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/types.h> /* For size_t */ 5099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_SYS_TYPES_H */ 5109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The maximum possible size_t value has all bits set */ 5129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAX_SIZE_T (~(size_t)0) 5139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef ONLY_MSPACES 5159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ONLY_MSPACES 0 5169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ONLY_MSPACES */ 5179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MSPACES 5189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ONLY_MSPACES 5199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MSPACES 1 5209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* ONLY_MSPACES */ 5219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MSPACES 0 5229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ONLY_MSPACES */ 5239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MSPACES */ 5249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MALLOC_ALIGNMENT 5259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MALLOC_ALIGNMENT ((size_t)8U) 5269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MALLOC_ALIGNMENT */ 5279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef FOOTERS 5289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define FOOTERS 0 5299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 5309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef ABORT 5319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ABORT abort() 5329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ABORT */ 5339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef ABORT_ON_ASSERT_FAILURE 5349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ABORT_ON_ASSERT_FAILURE 1 5359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ABORT_ON_ASSERT_FAILURE */ 5369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef PROCEED_ON_ERROR 5379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define PROCEED_ON_ERROR 0 5389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* PROCEED_ON_ERROR */ 5399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef USE_LOCKS 5409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_LOCKS 0 5419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS */ 5429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef INSECURE 5439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INSECURE 0 5449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* INSECURE */ 5459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_MMAP 5469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MMAP 1 5479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP */ 5489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MMAP_CLEARS 5499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_CLEARS 1 5509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MMAP_CLEARS */ 5519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_MREMAP 5529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef linux 5539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MREMAP 1 5549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* linux */ 5559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MREMAP 0 5569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* linux */ 5579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MREMAP */ 5589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MALLOC_FAILURE_ACTION 5599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MALLOC_FAILURE_ACTION errno = ENOMEM; 5609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MALLOC_FAILURE_ACTION */ 5619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef HAVE_MORECORE 5629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ONLY_MSPACES 5639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MORECORE 0 5649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* ONLY_MSPACES */ 5659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HAVE_MORECORE 1 5669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ONLY_MSPACES */ 5679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 5689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !HAVE_MORECORE 5699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MORECORE_CONTIGUOUS 0 5709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* !HAVE_MORECORE */ 5719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MORECORE 5729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MORECORE sbrk 5739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE */ 5749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MORECORE_CONTIGUOUS 5759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MORECORE_CONTIGUOUS 1 5769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE_CONTIGUOUS */ 5779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 5789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef DEFAULT_GRANULARITY 5799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MORECORE_CONTIGUOUS 5809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ 5819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MORECORE_CONTIGUOUS */ 5829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) 5839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE_CONTIGUOUS */ 5849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEFAULT_GRANULARITY */ 5859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef DEFAULT_TRIM_THRESHOLD 5869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MORECORE_CANNOT_TRIM 5879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) 5889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MORECORE_CANNOT_TRIM */ 5899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T 5909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE_CANNOT_TRIM */ 5919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEFAULT_TRIM_THRESHOLD */ 5929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef DEFAULT_MMAP_THRESHOLD 5939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MMAP 5949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) 5959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* HAVE_MMAP */ 5969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T 5979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP */ 5989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEFAULT_MMAP_THRESHOLD */ 5999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef USE_BUILTIN_FFS 6009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_BUILTIN_FFS 0 6019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_BUILTIN_FFS */ 6029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef USE_DEV_RANDOM 6039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_DEV_RANDOM 0 6049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_DEV_RANDOM */ 6059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef NO_MALLINFO 6069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define NO_MALLINFO 0 6079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 6089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MALLINFO_FIELD_TYPE 6099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MALLINFO_FIELD_TYPE size_t 6109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MALLINFO_FIELD_TYPE */ 6119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define memset SDL_memset 6139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define memcpy SDL_memcpy 6149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define malloc SDL_malloc 6159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define calloc SDL_calloc 6169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define realloc SDL_realloc 6179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define free SDL_free 6189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 6209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mallopt tuning options. SVID/XPG defines four standard parameter 6219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall numbers for mallopt, normally defined in malloc.h. None of these 6229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are used in this malloc, so setting them has no effect. But this 6239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc does support the following options. 6249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 6259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define M_TRIM_THRESHOLD (-1) 6279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define M_GRANULARITY (-2) 6289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define M_MMAP_THRESHOLD (-3) 6299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------ Mallinfo declarations ------------------------ */ 6319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 6339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 6349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This version of malloc supports the standard SVID/XPG mallinfo 6359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall routine that returns a struct containing usage properties and 6369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall statistics. It should work on any system that has a 6379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /usr/include/malloc.h defining struct mallinfo. The main 6389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall declaration needed is the mallinfo struct that is returned (by-copy) 6399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall by mallinfo(). The malloinfo struct contains a bunch of fields that 6409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are not even meaningful in this version of malloc. These fields are 6419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are instead filled by mallinfo() with other numbers that might be of 6429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall interest. 6439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall HAVE_USR_INCLUDE_MALLOC_H should be set if you have a 6459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /usr/include/malloc.h file that includes a declaration of struct 6469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mallinfo. If so, it is included; else a compliant version is 6479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall declared below. These must be precisely the same for mallinfo() to 6489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall work. The original SVID version of this struct, defined on most 6499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall systems with mallinfo, declares all fields as ints. But some others 6509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall define as unsigned long. If your system defines the fields using a 6519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall type of different width than listed here, you MUST #include your 6529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system version and #define HAVE_USR_INCLUDE_MALLOC_H. 6539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 6549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* #define HAVE_USR_INCLUDE_MALLOC_H */ 6569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef HAVE_USR_INCLUDE_MALLOC_H 6589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "/usr/include/malloc.h" 6599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* HAVE_USR_INCLUDE_MALLOC_H */ 6609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct mallinfo { 6629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ 6639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ 6649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE smblks; /* always 0 */ 6659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE hblks; /* always 0 */ 6669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ 6679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ 6689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ 6699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ 6709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE fordblks; /* total free space */ 6719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ 6729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 6739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_USR_INCLUDE_MALLOC_H */ 6759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 6769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef __cplusplus 6789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern "C" { 6799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* __cplusplus */ 6809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !ONLY_MSPACES 6829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------- Declarations of public routines ------------------- */ 6849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef USE_DL_PREFIX 6869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlcalloc calloc 6879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlfree free 6889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc malloc 6899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmemalign memalign 6909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlrealloc realloc 6919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlvalloc valloc 6929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlpvalloc pvalloc 6939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmallinfo mallinfo 6949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmallopt mallopt 6959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc_trim malloc_trim 6969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc_stats malloc_stats 6979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc_usable_size malloc_usable_size 6989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc_footprint malloc_footprint 6999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlmalloc_max_footprint malloc_max_footprint 7009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlindependent_calloc independent_calloc 7019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dlindependent_comalloc independent_comalloc 7029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_DL_PREFIX */ 7039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc(size_t n) 7079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns a pointer to a newly allocated chunk of at least n bytes, or 7089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall null if no space is available, in which case errno is set to ENOMEM 7099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall on ANSI C systems. 7109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If n is zero, malloc returns a minimum-sized chunk. (The minimum 7129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size is 16 bytes on most 32bit systems, and 32 bytes on 64bit 7139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall systems.) Note that size_t is an unsigned type, so calls with 7149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall arguments that would be negative if signed are interpreted as 7159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall requests for huge amounts of space, which will often fail. The 7169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall maximum supported value of n differs across systems, but is in all 7179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cases less than the maximum representable value of a size_t. 7189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlmalloc(size_t); 7209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free(void* p) 7239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Releases the chunk of memory pointed to by p, that had been previously 7249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocated using malloc or a related routine such as realloc. 7259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall It has no effect if p is null. If p was not malloced or already 7269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freed, free(p) will by default cause the current program to abort. 7279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid dlfree(void*); 7299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall calloc(size_t n_elements, size_t element_size); 7329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns a pointer to n_elements * element_size bytes, with all locations 7339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set to zero. 7349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlcalloc(size_t, size_t); 7369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall realloc(void* p, size_t n) 7399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns a pointer to a chunk of size n that contains the same data 7409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall as does chunk p up to the minimum of (n, p's size) bytes, or null 7419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if no space is available. 7429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The returned pointer may or may not be the same as p. The algorithm 7449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall prefers extending p in most cases when possible, otherwise it 7459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall employs the equivalent of a malloc-copy-free sequence. 7469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If p is null, realloc is equivalent to malloc. 7489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If space is not available, realloc returns null, errno is set (if on 7509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ANSI) and p is NOT freed. 7519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if n is for fewer bytes than already held by p, the newly unused 7539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space is lopped off and freed if possible. realloc with a size 7549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall argument of zero (re)allocates a minimum-sized chunk. 7559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The old unix realloc convention of allowing the last-free'd chunk 7579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to be used as an argument to realloc is not supported. 7589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlrealloc(void*, size_t); 7619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memalign(size_t alignment, size_t n); 7649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns a pointer to a newly allocated chunk of n bytes, aligned 7659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in accord with the alignment argument. 7669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The alignment argument should be a power of two. If the argument is 7689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall not a power of two, the nearest greater power is used. 7699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8-byte alignment is guaranteed by normal malloc calls, so don't 7709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bother calling memalign with an argument of 8 or less. 7719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Overreliance on memalign is a sure way to fragment space. 7739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlmemalign(size_t, size_t); 7759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall valloc(size_t n); 7789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Equivalent to memalign(pagesize, n), where pagesize is the page 7799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size of the system. If the pagesize is unknown, 4096 is used. 7809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 7819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlvalloc(size_t); 7829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 7849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mallopt(int parameter_number, int parameter_value) 7859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Sets tunable parameters The format is to provide a 7869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (parameter-number, parameter-value) pair. mallopt then sets the 7879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall corresponding parameter to the argument value if it can (i.e., so 7889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall long as the value is meaningful), and returns 1 if successful else 7899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, 7909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall normally defined in malloc.h. None of these are use in this malloc, 7919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall so setting them has no effect. But this malloc also supports other 7929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall options in mallopt. See below for details. Briefly, supported 7939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall parameters are as follows (listed defaults are for "typical" 7949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall configurations). 7959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Symbol param # default allowed param values 7979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall M_TRIM_THRESHOLD -1 2*1024*1024 any (MAX_SIZE_T disables) 7989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall M_GRANULARITY -2 page size any power of 2 >= page size 7999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) 8009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 8019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint dlmallopt(int, int); 8029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 8049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_footprint(); 8059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns the number of bytes obtained from the system. The total 8069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall number of bytes allocated by malloc, realloc etc., is less than this 8079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value. Unlike mallinfo, this function returns only a precomputed 8089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall result, so can be called frequently to monitor memory consumption. 8099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Even if locks are otherwise defined, this function does not use them, 8109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall so results might not be up to date. 8119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 8129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_footprint(void); 8139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 8159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_max_footprint(); 8169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns the maximum number of bytes obtained from the system. This 8179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value will be greater than current footprint if deallocated space 8189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall has been reclaimed by the system. The peak number of bytes allocated 8199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall by malloc, realloc etc., is less than this value. Unlike mallinfo, 8209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this function returns only a precomputed result, so can be called 8219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall frequently to monitor memory consumption. Even if locks are 8229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall otherwise defined, this function does not use them, so results might 8239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall not be up to date. 8249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 8259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_max_footprint(void); 8269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 8289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 8299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mallinfo() 8309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns (by copy) a struct containing various summary statistics: 8319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall arena: current total non-mmapped bytes allocated from system 8339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ordblks: the number of free chunks 8349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall smblks: always zero. 8359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hblks: current number of mmapped regions 8369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hblkhd: total bytes held in mmapped regions 8379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall usmblks: the maximum total allocated space. This will be greater 8389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall than current total if trimming has occurred. 8399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fsmblks: always zero 8409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uordblks: current total allocated space (normal or mmapped) 8419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fordblks: total free space 8429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall keepcost: the maximum number of bytes that could ideally be released 8439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall back to system via malloc_trim. ("ideally" means that 8449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall it ignores page restrictions etc.) 8459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Because these fields are ints, but internal bookkeeping may 8479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be kept as longs, the reported values may wrap around zero and 8489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall thus be inaccurate. 8499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 8509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct mallinfo dlmallinfo(void); 8519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 8529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 8549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); 8559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_calloc is similar to calloc, but instead of returning a 8579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall single cleared space, it returns an array of pointers to n_elements 8589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent elements that can hold contents of size elem_size, each 8599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of which starts out cleared, and can be independently freed, 8609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall realloc'ed etc. The elements are guaranteed to be adjacently 8619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocated (this is not guaranteed to occur with multiple callocs or 8629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mallocs), which may also improve cache locality in some 8639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall applications. 8649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The "chunks" argument is optional (i.e., may be null, which is 8669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall probably the most typical usage). If it is null, the returned array 8679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is itself dynamically allocated and should also be freed when it is 8689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall no longer needed. Otherwise, the chunks array must be of at least 8699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall n_elements in length. It is filled in with the pointers to the 8709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks. 8719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall In either case, independent_calloc returns this pointer array, or 8739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall null if the allocation failed. If n_elements is zero and "chunks" 8749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is null, it returns a chunk representing an array with zero elements 8759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (which should be freed if not wanted). 8769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each element must be individually freed when it is no longer 8789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall needed. If you'd like to instead be able to free all at once, you 8799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall should instead use regular calloc and assign pointers into this 8809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space to represent elements. (In this case though, you cannot 8819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independently free elements.) 8829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_calloc simplifies and speeds up implementations of many 8849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kinds of pools. It may also be useful when constructing large data 8859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall structures that initially have a fixed number of fixed-sized nodes, 8869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but the number is not known at compile time, and some of the nodes 8879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall may later need to be freed. For example: 8889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Node { int item; struct Node* next; }; 8909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Node* build_list() { 8929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Node** pool; 8939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int n = read_number_of_nodes_needed(); 8949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (n <= 0) return 0; 8959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); 8969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (pool == 0) die(); 8979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // organize into a linked list... 8989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Node* first = pool[0]; 8999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < n-1; ++i) 9009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pool[i]->next = pool[i+1]; 9019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free(pool); // Can now free the array (or not, if it is needed later) 9029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return first; 9039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 9059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** dlindependent_calloc(size_t, size_t, void**); 9069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 9089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); 9099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_comalloc allocates, all at once, a set of n_elements 9119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks with sizes indicated in the "sizes" array. It returns 9129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall an array of pointers to these elements, each of which can be 9139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independently freed, realloc'ed etc. The elements are guaranteed to 9149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be adjacently allocated (this is not guaranteed to occur with 9159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall multiple callocs or mallocs), which may also improve cache locality 9169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in some applications. 9179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The "chunks" argument is optional (i.e., may be null). If it is null 9199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the returned array is itself dynamically allocated and should also 9209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be freed when it is no longer needed. Otherwise, the chunks array 9219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall must be of at least n_elements in length. It is filled in with the 9229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointers to the chunks. 9239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall In either case, independent_comalloc returns this pointer array, or 9259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall null if the allocation failed. If n_elements is zero and chunks is 9269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall null, it returns a chunk representing an array with zero elements 9279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (which should be freed if not wanted). 9289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each element must be individually freed when it is no longer 9309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall needed. If you'd like to instead be able to free all at once, you 9319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall should instead use a single regular malloc, and assign pointers at 9329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall particular offsets in the aggregate space. (In this case though, you 9339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cannot independently free elements.) 9349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_comallac differs from independent_calloc in that each 9369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall element may have a different size, and also that it does not 9379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall automatically clear elements. 9389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall independent_comalloc can be used to speed up allocation in cases 9409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall where several structs or objects must always be allocated at the 9419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall same time. For example: 9429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Head { ... } 9449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Foot { ... } 9459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void send_message(char* msg) { 9479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int msglen = strlen(msg); 9489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; 9499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* chunks[3]; 9509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (independent_comalloc(3, sizes, chunks) == 0) 9519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall die(); 9529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Head* head = (struct Head*)(chunks[0]); 9539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* body = (char*)(chunks[1]); 9549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct Foot* foot = (struct Foot*)(chunks[2]); 9559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // ... 9569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall In general though, independent_comalloc is worth using only for 9599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall larger values of n_elements. For small values, you probably won't 9609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall detect enough difference from series of malloc calls to bother. 9619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Overuse of independent_comalloc can increase overall memory usage, 9639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall since it cannot reuse existing noncontiguous small chunks that 9649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall might be available for some of the elements. 9659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 9669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** dlindependent_comalloc(size_t, size_t*, void**); 9679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 9709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pvalloc(size_t n); 9719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Equivalent to valloc(minimum-page-that-holds(n)), that is, 9729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall round up n to nearest pagesize. 9739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 9749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlpvalloc(size_t); 9759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 9779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_trim(size_t pad); 9789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If possible, gives memory back to the system (via negative arguments 9809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to sbrk) if there is unused memory at the `high' end of the malloc 9819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pool or in unused MMAP segments. You can call this after freeing 9829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall large blocks of memory to potentially reduce the system-level memory 9839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall requirements of a program. However, it cannot guarantee to reduce 9849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory. Under some allocation patterns, some large free blocks of 9859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory will be locked between two used chunks, so they cannot be 9869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall given back to the system. 9879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The `pad' argument to malloc_trim represents the amount of free 9899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall trailing space to leave untrimmed. If this argument is zero, only 9909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the minimum amount of memory to maintain internal data structures 9919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall will be left. Non-zero arguments can be supplied to maintain enough 9929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall trailing space to service future expected allocations without having 9939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to re-obtain memory from the system. 9949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Malloc_trim returns 1 if it actually released any memory, else 0. 9969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 9979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint dlmalloc_trim(size_t); 9989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_usable_size(void* p); 10019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Returns the number of bytes you can actually use in 10039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall an allocated chunk, which may be more than you requested (although 10049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall often not) due to alignment and minimum size constraints. 10059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You can use this many bytes without worrying about 10069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overwriting other allocated objects. This is not a particularly great 10079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall programming practice. malloc_usable_size can be more useful in 10089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall debugging and assertions, for example: 10099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = malloc(n); 10119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(malloc_usable_size(p) >= 256); 10129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_usable_size(void*); 10149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_stats(); 10179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Prints on stderr the amount of space obtained from the system (both 10189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall via sbrk and mmap), the maximum amount (which may be more than 10199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current if malloc_trim and/or munmap got called), and the current 10209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall number of bytes allocated via malloc (or realloc, etc) but not yet 10219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freed. Note that this is the number of bytes allocated, not the 10229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall number requested. It will be larger than the number requested 10239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall because of alignment and bookkeeping overhead. Because it includes 10249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignment wastage as being in use, this figure may be greater than 10259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall zero even when no user-level chunks are allocated. 10269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The reported current and maximum system memory can be inaccurate if 10289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall a program makes other calls to system memory allocation functions 10299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (normally sbrk) outside of malloc. 10309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_stats prints only the most commonly interesting statistics. 10329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall More information can be obtained by calling mallinfo. 10339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid dlmalloc_stats(void); 10359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ONLY_MSPACES */ 10379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MSPACES 10399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace is an opaque type representing an independent 10429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall region of space that supports mspace_malloc, etc. 10439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef void* mspace; 10459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall create_mspace creates and returns a new independent space with the 10489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall given initial capacity, or, if 0, the default granularity size. It 10499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall returns null if there is no system memory available to create the 10509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space. If argument locked is non-zero, the space uses a separate 10519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lock to control access. The capacity of the space will grow 10529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dynamically as needed to service mspace_malloc requests. You can 10539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall control the sizes of incremental increases of this space by 10549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compiling with a different DEFAULT_GRANULARITY or dynamically 10559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall setting with mallopt(M_GRANULARITY, value). 10569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallmspace create_mspace(size_t capacity, int locked); 10589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall destroy_mspace destroys the given space, and attempts to return all 10619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of its memory back to the system, returning the total number of 10629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bytes freed. After destruction, the results of access to all memory 10639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used by the space become undefined. 10649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t destroy_mspace(mspace msp); 10669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall create_mspace_with_base uses the memory supplied as the initial base 10699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this 10709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space is used for bookkeeping, so the capacity must be at least this 10719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall large. (Otherwise 0 is returned.) When this initial space is 10729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exhausted, additional memory will be obtained from the system. 10739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Destroying this space will deallocate all additionally allocated 10749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space (if possible) but not the initial base. 10759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallmspace create_mspace_with_base(void* base, size_t capacity, int locked); 10779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_malloc behaves as malloc, but operates within 10809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 10819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_malloc(mspace msp, size_t bytes); 10839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_free behaves as free, but operates within 10869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 10879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If compiled with FOOTERS==1, mspace_free is not actually needed. 10899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free may be called instead of mspace_free because freed chunks from 10909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall any space are handled by their originating spaces. 10919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 10929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid mspace_free(mspace msp, void* mem); 10939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 10959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_realloc behaves as realloc, but operates within 10969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 10979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If compiled with FOOTERS==1, mspace_realloc is not actually 10999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall needed. realloc may be called instead of mspace_realloc because 11009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall realloced chunks from any space are handled by their originating 11019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spaces. 11029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_realloc(mspace msp, void* mem, size_t newsize); 11049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_calloc behaves as calloc, but operates within 11079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 11089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); 11109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_memalign behaves as memalign, but operates within 11139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 11149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_memalign(mspace msp, size_t alignment, size_t bytes); 11169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_independent_calloc behaves as independent_calloc, but 11199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall operates within the given space. 11209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** mspace_independent_calloc(mspace msp, size_t n_elements, 11229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t elem_size, void* chunks[]); 11239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_independent_comalloc behaves as independent_comalloc, but 11269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall operates within the given space. 11279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** mspace_independent_comalloc(mspace msp, size_t n_elements, 11299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sizes[], void* chunks[]); 11309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_footprint() returns the number of bytes obtained from the 11339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system for this space. 11349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t mspace_footprint(mspace msp); 11369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_max_footprint() returns the peak number of bytes obtained from the 11399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system for this space. 11409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t mspace_max_footprint(mspace msp); 11429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 11459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_mallinfo behaves as mallinfo, but reports properties of 11479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the given space. 11489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct mallinfo mspace_mallinfo(mspace msp); 11509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 11519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_malloc_stats behaves as malloc_stats, but reports 11549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall properties of the given space. 11559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid mspace_malloc_stats(mspace msp); 11579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_trim behaves as malloc_trim, but 11609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall operates within the given space. 11619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint mspace_trim(mspace msp, size_t pad); 11639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall An alias for mallopt. 11669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint mspace_mallopt(int, int); 11689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MSPACES */ 11709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef __cplusplus 11729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; /* end of extern "C" */ 11739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* __cplusplus */ 11749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 11769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ======================================================================== 11779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall To make a fully customizable malloc.h header file, cut everything 11789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall above this line, put into file malloc.h, edit to suit, and #include it 11799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall on the next line, as well as in programs that use this malloc. 11809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ======================================================================== 11819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 11829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* #include "malloc.h" */ 11849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*------------------------------ internal #includes ---------------------- */ 11869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef _MSC_VER 11889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ 11899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* _MSC_VER */ 11909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_STDIO_H 11929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h> /* for printing in malloc_stats */ 11939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 11949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_ERRNO_H 11969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <errno.h> /* for MALLOC_FAILURE_ACTION */ 11979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_ERRNO_H */ 11989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if FOOTERS 11999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <time.h> /* for magic initialization */ 12009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 12019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_STDLIB_H 12029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdlib.h> /* for abort() */ 12039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_STDLIB_H */ 12049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG 12059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ABORT_ON_ASSERT_FAILURE 12069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define assert(x) if(!(x)) ABORT 12079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* ABORT_ON_ASSERT_FAILURE */ 12089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <assert.h> 12099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ABORT_ON_ASSERT_FAILURE */ 12109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* DEBUG */ 12119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define assert(x) 12129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEBUG */ 12139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_STRING_H 12149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <string.h> /* for memset etc */ 12159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_STRING_H */ 12169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_BUILTIN_FFS 12179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_STRINGS_H 12189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <strings.h> /* for ffs */ 12199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_STRINGS_H */ 12209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_BUILTIN_FFS */ 12219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MMAP 12229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_SYS_MMAN_H 12239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/mman.h> /* for mmap */ 12249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_SYS_MMAN_H */ 12259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_FCNTL_H 12269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <fcntl.h> 12279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_FCNTL_H */ 12289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP */ 12299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MORECORE 12309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_UNISTD_H 12319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <unistd.h> /* for sbrk */ 12329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* LACKS_UNISTD_H */ 12339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) 12349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern void* sbrk(ptrdiff_t); 12359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FreeBSD etc */ 12369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* LACKS_UNISTD_H */ 12379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP */ 12389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef WIN32 12409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef malloc_getpagesize 12419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ 12429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifndef _SC_PAGE_SIZE 12439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define _SC_PAGE_SIZE _SC_PAGESIZE 12449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef _SC_PAGE_SIZE 12479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) 12489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) 12509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extern size_t getpagesize(); 12519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize getpagesize() 12529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef WIN32 /* use supplied emulation of getpagesize */ 12549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize getpagesize() 12559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifndef LACKS_SYS_PARAM_H 12579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# include <sys/param.h> 12589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef EXEC_PAGESIZE 12609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize EXEC_PAGESIZE 12619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef NBPG 12639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifndef CLSIZE 12649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize NBPG 12659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize (NBPG * CLSIZE) 12679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef NBPC 12709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize NBPC 12719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else 12729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# ifdef PAGESIZE 12739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize PAGESIZE 12749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# else /* just guess */ 12759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# define malloc_getpagesize ((size_t)4096U) 12769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 12839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------- size_t and alignment properties -------------------- */ 12879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The byte and bit size of a size_t */ 12899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIZE_T_SIZE (sizeof(size_t)) 12909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIZE_T_BITSIZE (sizeof(size_t) << 3) 12919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Some constants coerced to size_t */ 12939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Annoying but necessary to avoid errors on some plaftorms */ 12949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIZE_T_ZERO ((size_t)0) 12959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIZE_T_ONE ((size_t)1) 12969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIZE_T_TWO ((size_t)2) 12979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) 12989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) 12999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) 13009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) 13019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The bit mask value corresponding to MALLOC_ALIGNMENT */ 13039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) 13049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* True if address a has acceptable alignment */ 13069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) 13079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* the number of bytes to offset an address to align it */ 13099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define align_offset(A)\ 13109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ 13119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) 13129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- MMAP preliminaries ------------------------- */ 13149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 13169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and 13179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall checks to fail so compiler optimizer can delete code rather than 13189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using so many "#if"s. 13199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 13209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* MORECORE and MMAP must return MFAIL on failure */ 13239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MFAIL ((void*)(MAX_SIZE_T)) 13249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ 13259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !HAVE_MMAP 13279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define IS_MMAPPED_BIT (SIZE_T_ZERO) 13289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_MMAP_BIT (SIZE_T_ZERO) 13299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MMAP(s) MFAIL 13309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MUNMAP(a, s) (-1) 13319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DIRECT_MMAP(s) MFAIL 13329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* HAVE_MMAP */ 13349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define IS_MMAPPED_BIT (SIZE_T_ONE) 13359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_MMAP_BIT (SIZE_T_ONE) 13369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef WIN32 13389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MUNMAP(a, s) munmap((a), (s)) 13399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_PROT (PROT_READ|PROT_WRITE) 13409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) 13419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAP_ANONYMOUS MAP_ANON 13429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MAP_ANON */ 13439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef MAP_ANONYMOUS 13449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) 13459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) 13469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MAP_ANONYMOUS */ 13479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 13489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Nearly all versions of mmap support MAP_ANONYMOUS, so the following 13499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is unlikely to be needed, but is supplied just in case. 13509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 13519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_FLAGS (MAP_PRIVATE) 13529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ 13539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ 13549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (dev_zero_fd = open("/dev/zero", O_RDWR), \ 13559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ 13569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) 13579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MAP_ANONYMOUS */ 13589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DIRECT_MMAP(s) CALL_MMAP(s) 13609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* WIN32 */ 13619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Win32 MMAP via VirtualAlloc */ 13639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* win32mmap(size_t size) { 13649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 13659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (ptr != 0)? ptr: MFAIL; 13669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ 13699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* win32direct_mmap(size_t size) { 13709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, 13719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PAGE_READWRITE); 13729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (ptr != 0)? ptr: MFAIL; 13739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* This function supports releasing coalesed segments */ 13769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int win32munmap(void* ptr, size_t size) { 13779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MEMORY_BASIC_INFORMATION minfo; 13789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* cptr = ptr; 13799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (size) { 13809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) 13819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 13829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || 13839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall minfo.State != MEM_COMMIT || minfo.RegionSize > size) 13849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 13859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) 13869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 13879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cptr += minfo.RegionSize; 13889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size -= minfo.RegionSize; 13899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 13919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MMAP(s) win32mmap(s) 13949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MUNMAP(a, s) win32munmap((a), (s)) 13959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DIRECT_MMAP(s) win32direct_mmap(s) 13969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* WIN32 */ 13979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP */ 13989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MMAP && HAVE_MREMAP 14009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) 14019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* HAVE_MMAP && HAVE_MREMAP */ 14029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL 14039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MMAP && HAVE_MREMAP */ 14049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MORECORE 14069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MORECORE(S) MORECORE(S) 14079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* HAVE_MORECORE */ 14089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CALL_MORECORE(S) MFAIL 14099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 14109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* mstate bit set if continguous morecore disabled or failed */ 14129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_NONCONTIGUOUS_BIT (4U) 14139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* segment bit set in create_mspace_with_base */ 14159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define EXTERN_BIT (8U) 14169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* --------------------------- Lock preliminaries ------------------------ */ 14199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_LOCKS 14219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 14239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall When locks are defined, there are up to two global locks: 14249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * If HAVE_MORECORE, morecore_mutex protects sequences of calls to 14269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MORECORE. In many cases sys_alloc requires two calls, that should 14279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall not be interleaved with calls by other threads. This does not 14289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall protect against direct calls to MORECORE by other threads not 14299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using this lock, so there is still code to cope the best we can on 14309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall interference. 14319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * magic_init_mutex ensures that mparams.magic and other 14339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unique mparams values are initialized only once. 14349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 14359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef WIN32 14379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* By default use posix locks */ 14389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <pthread.h> 14399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MLOCK_T pthread_mutex_t 14409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INITIAL_LOCK(l) pthread_mutex_init(l, NULL) 14419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_LOCK(l) pthread_mutex_lock(l) 14429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_LOCK(l) pthread_mutex_unlock(l) 14439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MORECORE 14459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER; 14469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 14479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER; 14499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* WIN32 */ 14519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 14529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Because lock-protected regions have bounded times, and there 14539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are no recursive lock calls, we can use simple spinlocks. 14549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 14559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MLOCK_T long 14579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int win32_acquire_lock (MLOCK_T *sl) { 14589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) { 14599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef InterlockedCompareExchangePointer 14609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!InterlockedCompareExchange(sl, 1, 0)) 14619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 14629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* Use older void* version */ 14639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0)) 14649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 14659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* InterlockedCompareExchangePointer */ 14669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Sleep (0); 14679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void win32_release_lock (MLOCK_T *sl) { 14719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall InterlockedExchange (sl, 0); 14729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INITIAL_LOCK(l) *(l)=0 14759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_LOCK(l) win32_acquire_lock(l) 14769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_LOCK(l) win32_release_lock(l) 14779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if HAVE_MORECORE 14789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic MLOCK_T morecore_mutex; 14799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* HAVE_MORECORE */ 14809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic MLOCK_T magic_init_mutex; 14819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* WIN32 */ 14829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_LOCK_BIT (2U) 14849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* USE_LOCKS */ 14859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USE_LOCK_BIT (0U) 14869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INITIAL_LOCK(l) 14879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS */ 14889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_LOCKS && HAVE_MORECORE 14909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex); 14919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex); 14929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* USE_LOCKS && HAVE_MORECORE */ 14939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_MORECORE_LOCK() 14949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_MORECORE_LOCK() 14959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS && HAVE_MORECORE */ 14969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_LOCKS 14989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); 14999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); 15009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* USE_LOCKS */ 15019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ACQUIRE_MAGIC_INIT_LOCK() 15029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RELEASE_MAGIC_INIT_LOCK() 15039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS */ 15049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------- Chunk representations ------------------------ */ 15079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 15099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (The following includes lightly edited explanations by Colin Plumb.) 15109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The malloc_chunk declaration below is misleading (but accurate and 15129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall necessary). It declares a "view" into memory allowing access to 15139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall necessary fields at known offsets from a given base. 15149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Chunks of memory are maintained using a `boundary tag' method as 15169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall originally described by Knuth. (See the paper by Paul Wilson 15179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such 15189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall techniques.) Sizes of free chunks are stored both in the front of 15199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall each chunk and at the end. This makes consolidating fragmented 15209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks into bigger chunks fast. The head fields also hold bits 15219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall representing whether chunks are free or in use. 15229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Here are some pictures to make it clearer. They are "exploded" to 15249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall show that the state of a chunk can be thought of as extending from 15259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the high 31 bits of the head field of its header through the 15269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall prev_foot and PINUSE_BIT bit of the following chunk header. 15279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall A chunk that's in use looks like: 15299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of previous chunk (if P = 1) | 15329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| 15349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of this chunk 1| +-+ 15359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | | 15379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +- -+ 15389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | | 15399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +- -+ 15409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | : 15419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +- size - sizeof(size_t) available payload bytes -+ 15429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall : | 15439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +- -+ 15449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | | 15459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| 15479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of next chunk (may or may not be in use) | +-+ 15489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall And if it's free, it looks like this: 15519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +- -+ 15539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | User payload (must be in use, or we would have merged!) | 15549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| 15569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of this chunk 0| +-+ 15579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Next pointer | 15599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Prev pointer | 15619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | : 15639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +- size - sizeof(struct chunk) unused bytes -+ 15649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall : | 15659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of this chunk | 15679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| 15699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of next chunk (must be in use, or we would have merged)| +-+ 15709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | : 15729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +- User payload -+ 15739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall : | 15749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall |0| 15769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+ 15779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Note that since we always merge adjacent free chunks, the chunks 15789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall adjacent to a free chunk must be in use. 15799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Given a pointer to a chunk (which can be derived trivially from the 15819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall payload pointer) we can, in O(1) time, find out whether the adjacent 15829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks are free, and if so, unlink them from the lists that they 15839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall are on and merge them with the current chunk. 15849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Chunks always begin on even word boundaries, so the mem portion 15869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (which is returned to the user) is also on an even word boundary, and 15879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall thus at least double-word aligned. 15889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The P (PINUSE_BIT) bit, stored in the unused low-order bit of the 15909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk size (which is always a multiple of two words), is an in-use 15919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bit for the *previous* chunk. If that bit is *clear*, then the 15929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall word before the current chunk size contains the previous chunk 15939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size, and can be used to find the front of the previous chunk. 15949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The very first chunk allocated always has this bit set, preventing 15959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall access to non-existent (or non-owned) memory. If pinuse is set for 15969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall any given chunk, then you CANNOT determine the size of the 15979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall previous chunk, and might even get a memory addressing fault when 15989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall trying to do so. 15999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of 16019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the chunk size redundantly records whether the current chunk is 16029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall inuse. This redundancy enables usage checks within free and realloc, 16039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and reduces indirection when freeing and consolidating chunks. 16049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each freshly allocated chunk must have both cinuse and pinuse set. 16069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall That is, each allocated chunk borders either a previously allocated 16079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and still in-use chunk, or the base of its memory arena. This is 16089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ensured by making all allocations from the the `lowest' part of any 16099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall found chunk. Further, no free chunk physically borders another one, 16109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall so each free chunk is known to be preceded and followed by either 16119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall inuse chunks or the ends of memory. 16129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Note that the `foot' of the current chunk is actually represented 16149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall as the prev_foot of the NEXT chunk. This makes it easier to 16159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deal with alignments etc but can be very confusing when trying 16169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to extend or adapt this code. 16179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The exceptions to all this are 16199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1. The special chunk `top' is the top-most available chunk (i.e., 16219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the one bordering the end of available memory). It is treated 16229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall specially. Top is never included in any bin, is used only if 16239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall no other chunk is available, and is released back to the 16249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system if it is very large (see M_TRIM_THRESHOLD). In effect, 16259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the top chunk is treated as larger (and thus less well 16269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fitting) than any other available chunk. The top chunk 16279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall doesn't update its trailing size field since there is no next 16289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contiguous chunk that would have to index off it. However, 16299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space is still allocated for it (TOP_FOOT_SIZE) to enable 16309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall separation or merging when space is extended. 16319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3. Chunks allocated via mmap, which have the lowest-order bit 16339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set 16349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PINUSE_BIT in their head fields. Because they are allocated 16359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall one-by-one, each must carry its own prev_foot field, which is 16369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall also used to hold the offset this chunk has within its mmapped 16379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall region, which is needed to preserve alignment. Each mmapped 16389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk is trailed by the first two fields of a fake next-chunk 16399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for sake of usage checks. 16409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 16429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct malloc_chunk { 16449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t prev_foot; /* Size of previous chunk (if free). */ 16459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t head; /* Size and inuse bits. */ 16469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_chunk* fd; /* double links -- used only if free. */ 16479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_chunk* bk; 16489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 16499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_chunk mchunk; 16519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_chunk* mchunkptr; 16529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ 16539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef size_t bindex_t; /* Described below */ 16549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef unsigned int binmap_t; /* Described below */ 16559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef unsigned int flag_t; /* The type of various bit flag sets */ 16569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------- Chunks sizes and alignments ----------------------- */ 16589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MCHUNK_SIZE (sizeof(mchunk)) 16609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if FOOTERS 16629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) 16639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 16649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CHUNK_OVERHEAD (SIZE_T_SIZE) 16659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 16669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* MMapped chunks need a second word of overhead ... */ 16689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) 16699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ... and additional padding for fake next-chunk at foot */ 16709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) 16719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The smallest size we can malloc is an aligned minimal chunk */ 16739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MIN_CHUNK_SIZE\ 16749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 16759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* conversion from malloc headers to user pointers, and back */ 16779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) 16789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) 16799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* chunk associated with aligned address A */ 16809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) 16819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bounds on request (not chunk) sizes. */ 16839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) 16849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) 16859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* pad request bytes into a usable size */ 16879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define pad_request(req) \ 16889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 16899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* pad request, checking for minimum (but not maximum) */ 16919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define request2size(req) \ 16929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) 16939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------ Operations on head and foot fields ----------------- */ 16969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 16989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The head field of a chunk is or'ed with PINUSE_BIT when previous 16999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in 17009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall use. If the chunk was obtained with mmap, the prev_foot field has 17019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall IS_MMAPPED_BIT set, otherwise holding the offset of the base of the 17029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mmapped region to the base of the chunk. 17039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 17049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define PINUSE_BIT (SIZE_T_ONE) 17069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CINUSE_BIT (SIZE_T_TWO) 17079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) 17089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Head value for fenceposts */ 17109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) 17119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* extraction of fields from head words */ 17139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define cinuse(p) ((p)->head & CINUSE_BIT) 17149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define pinuse(p) ((p)->head & PINUSE_BIT) 17159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define chunksize(p) ((p)->head & ~(INUSE_BITS)) 17169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) 17189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) 17199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Treat space at ptr +/- offset as a chunk */ 17219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) 17229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) 17239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Ptr to next or previous physical malloc_chunk. */ 17259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS))) 17269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) 17279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* extract next chunk's pinuse bit */ 17299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) 17309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get/set size at footer */ 17329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) 17339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) 17349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set size, pinuse bit, and foot */ 17369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_size_and_pinuse_of_free_chunk(p, s)\ 17379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) 17389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set size, pinuse bit, foot, and clear next pinuse */ 17409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_free_with_pinuse(p, s, n)\ 17419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) 17429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_mmapped(p)\ 17449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) 17459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get the internal overhead associated with chunk p */ 17479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define overhead_for(p)\ 17489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) 17499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Return true if malloced space is not necessarily cleared */ 17519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MMAP_CLEARS 17529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define calloc_must_clear(p) (!is_mmapped(p)) 17539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MMAP_CLEARS */ 17549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define calloc_must_clear(p) (1) 17559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MMAP_CLEARS */ 17569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ---------------------- Overlaid data structures ----------------------- */ 17589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 17609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall When chunks are not in use, they are treated as nodes of either 17619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lists or trees. 17629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "Small" chunks are stored in circular doubly-linked lists, and look 17649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall like this: 17659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of previous chunk | 17689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall `head:' | Size of chunk, in bytes |P| 17709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Forward pointer to next chunk in list | 17729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Back pointer to previous chunk in list | 17749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Unused space (may be 0 bytes long) . 17769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall . . 17779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall . | 17789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallnextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall `foot:' | Size of chunk, in bytes | 17809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Larger chunks are kept in a form of bitwise digital trees (aka 17839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tries) keyed on chunksizes. Because malloc_tree_chunks are only for 17849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free chunks greater than 256 bytes, their size doesn't impose any 17859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall constraints on user chunk sizes. Each node looks like: 17869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 17879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Size of previous chunk | 17899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall `head:' | Size of chunk, in bytes |P| 17919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Forward pointer to next chunk of same size | 17939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Back pointer to previous chunk of same size | 17959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Pointer to left child (child[0]) | 17979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Pointer to right child (child[1]) | 17999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Pointer to parent | 18019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | bin index of this chunk | 18039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall | Unused space . 18059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall . | 18069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallnextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall `foot:' | Size of chunk, in bytes | 18089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each tree holding treenodes is a tree of unique chunk sizes. Chunks 18119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of the same size are arranged in a circularly-linked list, with only 18129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the oldest chunk (the next to be used, in our FIFO ordering) 18139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall actually in the tree. (Tree members are distinguished by a non-null 18149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall parent pointer.) If a chunk with the same size an an existing node 18159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is inserted, it is linked off the existing node using pointers that 18169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall work in the same way as fd/bk pointers of small chunks. 18179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each tree contains a power of 2 sized range of chunk sizes (the 18199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall smallest is 0x100 <= x < 0x180), which is is divided in half at each 18209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tree level, with the chunks in the smaller half of the range (0x100 18219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall <= x < 0x140 for the top nose) in the left subtree and the larger 18229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall half (0x140 <= x < 0x180) in the right subtree. This is, of course, 18239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall done by inspecting individual bits. 18249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Using these rules, each node's left subtree contains all smaller 18269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sizes than its right subtree. However, the node at the root of each 18279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall subtree has no particular ordering relationship to either. (The 18289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dividing line between the subtree sizes is based on trie relation.) 18299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If we remove the last chunk of a given size from the interior of the 18309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tree, we need to replace it with a leaf node. The tree ordering 18319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rules permit a node to be replaced by any leaf below it. 18329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The smallest chunk in a tree (a common operation in a best-fit 18349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocator) can be found by walking a path to the leftmost leaf in 18359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the tree. Unlike a usual binary tree, where we follow left child 18369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointers until we reach a null, here we follow the right child 18379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointer any time the left one is null, until we reach a leaf with 18389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall both child pointers null. The smallest chunk in the tree will be 18399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall somewhere along that path. 18409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The worst case number of steps to add, find, or remove a node is 18429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bounded by the number of bits differentiating chunks within 18439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bins. Under current bin calculations, this ranges from 6 up to 21 18449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case 18459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is of course much better. 18469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 18479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct malloc_tree_chunk { 18499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* The first four fields must be compatible with malloc_chunk */ 18509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t prev_foot; 18519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t head; 18529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_tree_chunk* fd; 18539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_tree_chunk* bk; 18549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_tree_chunk* child[2]; 18569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_tree_chunk* parent; 18579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t index; 18589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 18599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_tree_chunk tchunk; 18619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_tree_chunk* tchunkptr; 18629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ 18639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* A little helper macro for trees */ 18659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) 18669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------------- Segments -------------------------------- */ 18689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 18709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each malloc space may include non-contiguous segments, held in a 18719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall list headed by an embedded malloc_segment record representing the 18729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall top-most space. Segments also include flags holding properties of 18739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the space. Large chunks that are directly allocated by mmap are not 18749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall included in this list. They are instead independently created and 18759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall destroyed without otherwise keeping track of them. 18769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Segment management mainly comes into play for spaces allocated by 18789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MMAP. Any call to MMAP might or might not return memory that is 18799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall adjacent to an existing segment. MORECORE normally contiguously 18809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extends the current space, so this space is almost always adjacent, 18819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall which is simpler and faster to deal with. (This is why MORECORE is 18829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used preferentially to MMAP when both are available -- see 18839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sys_alloc.) When allocating using MMAP, we don't use any of the 18849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hinting mechanisms (inconsistently) supported in various 18859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall implementations of unix mmap, or distinguish reserving from 18869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall committing memory. Instead, we just ask for space, and exploit 18879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contiguity when we get it. It is probably possible to do 18889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall better than this on some systems, but no general scheme seems 18899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to be significantly better. 18909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Management entails a simpler variant of the consolidation scheme 18929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used for chunks to reduce fragmentation -- new adjacent memory is 18939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall normally prepended or appended to an existing segment. However, 18949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall there are limitations compared to chunk consolidation that mostly 18959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall reflect the fact that segment processing is relatively infrequent 18969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (occurring only when getting memory from system) and that we 18979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall don't expect to have huge numbers of segments: 18989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 18999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Segments are not indexed, so traversal requires linear scans. (It 19009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall would be possible to index these, but is not worth the extra 19019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overhead and complexity for most programs on most platforms.) 19029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * New segments are only appended to old ones when holding top-most 19039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory; if they cannot be prepended to others, they are held in 19049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall different segments. 19059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Except for the top-most segment of an mstate, each segment record 19079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is kept at the tail of its segment. Segments are added by pushing 19089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall segment records onto the list headed by &mstate.seg for the 19099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall containing mstate. 19109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Segment flags control allocation/merge/deallocation policies: 19129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * If EXTERN_BIT set, then we did not allocate this segment, 19139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and so should not try to deallocate or merge with others. 19149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (This currently holds only for the initial segment passed 19159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall into create_mspace_with_base.) 19169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * If IS_MMAPPED_BIT set, the segment may be merged with 19179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall other surrounding mmapped segments and trimmed/de-allocated 19189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall using munmap. 19199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * If neither bit is set, then the segment was obtained using 19209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MORECORE so can be merged with surrounding MORECORE'd segments 19219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and deallocated/trimmed using MORECORE with negative arguments. 19229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 19239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct malloc_segment { 19259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* base; /* base address */ 19269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size; /* allocated size */ 19279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct malloc_segment* next; /* ptr to next segment */ 19289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t sflags; /* mmap and extern flag */ 19299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 19309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) 19329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) 19339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_segment msegment; 19359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_segment* msegmentptr; 19369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ---------------------------- malloc_state ----------------------------- */ 19389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 19409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall A malloc_state holds all of the bookkeeping for a space. 19419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The main fields are: 19429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Top 19449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The topmost chunk of the currently active segment. Its size is 19459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cached in topsize. The actual size of topmost space is 19469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall topsize+TOP_FOOT_SIZE, which includes space reserved for adding 19479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fenceposts and segment records if necessary when getting more 19489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space from the system. The size at which to autotrim top is 19499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cached from mparams in trim_check, except that it is disabled if 19509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall an autotrim fails. 19519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Designated victim (dv) 19539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This is the preferred chunk for servicing small requests that 19549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall don't have exact fits. It is normally the chunk split off most 19559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall recently to service another small request. Its size is cached in 19569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dvsize. The link fields of this chunk are not maintained since it 19579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall is not kept in a bin. 19589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SmallBins 19609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall An array of bin headers for free chunks. These bins hold chunks 19619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with sizes less than MIN_LARGE_SIZE bytes. Each bin contains 19629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunks of all the same size, spaced 8 bytes apart. To simplify 19639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall use in double-linked lists, each bin header acts as a malloc_chunk 19649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pointing to the real first node, if it exists (else pointing to 19659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall itself). This avoids special-casing for headers. But to avoid 19669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall waste, we allocate only the fd/bk pointers of bins, and then use 19679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall repositioning tricks to treat these as the fields of a chunk. 19689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall TreeBins 19709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Treebins are pointers to the roots of trees holding a range of 19719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sizes. There are 2 equally spaced treebins for each power of two 19729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything 19739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall larger. 19749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Bin maps 19769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall There is one bit map for small bins ("smallmap") and one for 19779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall treebins ("treemap). Each bin sets its bit when non-empty, and 19789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall clears the bit when empty. Bit operations are then used to avoid 19799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bin-by-bin searching -- nearly all "search" is done without ever 19809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall looking at bins that won't be selected. The bit maps 19819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall conservatively use 32 bits per map word, even if on 64bit system. 19829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall For a good description of some of the bit-based techniques used 19839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall here, see Henry S. Warren Jr's book "Hacker's Delight" (and 19849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall supplement at http://hackersdelight.org/). Many of these are 19859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall intended to reduce the branchiness of paths through malloc etc, as 19869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall well as to reduce the number of memory locations read or written. 19879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Segments 19899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall A list of segments headed by an embedded malloc_segment record 19909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall representing the initial space. 19919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Address check support 19939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The least_addr field is the least address ever obtained from 19949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MORECORE or MMAP. Attempted frees and reallocs of any address less 19959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall than this are trapped (unless INSECURE is defined). 19969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 19979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Magic tag 19989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall A cross-check field that should always hold same value as mparams.magic. 19999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Flags 20019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Bits recording whether to use MMAP, locks, or contiguous MORECORE 20029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Statistics 20049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Each space keeps track of current and maximum system memory 20059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall obtained via MORECORE or MMAP. 20069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Locking 20089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If USE_LOCKS is defined, the "mutex" lock is acquired and released 20099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall around every public call using this mspace. 20109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 20119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bin types, widths and sizes */ 20139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define NSMALLBINS (32U) 20149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define NTREEBINS (32U) 20159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SMALLBIN_SHIFT (3U) 20169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) 20179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define TREEBIN_SHIFT (8U) 20189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) 20199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) 20209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) 20219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct malloc_state { 20239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t smallmap; 20249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t treemap; 20259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dvsize; 20269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t topsize; 20279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* least_addr; 20289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr dv; 20299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr top; 20309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t trim_check; 20319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t magic; 20329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr smallbins[(NSMALLBINS+1)*2]; 20339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbinptr treebins[NTREEBINS]; 20349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t footprint; 20359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t max_footprint; 20369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t mflags; 20379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_LOCKS 20389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MLOCK_T mutex; /* locate lock among fields that rarely change */ 20399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS */ 20409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegment seg; 20419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 20429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef struct malloc_state* mstate; 20449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------- Global malloc_state and malloc_params ------------------- */ 20469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 20489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_params holds global properties, including those that can be 20499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dynamically set using mallopt. There is a single instance, mparams, 20509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initialized in init_mparams. 20519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 20529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct malloc_params { 20549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t magic; 20559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t page_size; 20569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t granularity; 20579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t mmap_threshold; 20589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t trim_threshold; 20599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t default_mflags; 20609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 20619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic struct malloc_params mparams; 20639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The global malloc_state used for all non-"mspace" calls */ 20659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic struct malloc_state _gm_; 20669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define gm (&_gm_) 20679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_global(M) ((M) == &_gm_) 20689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_initialized(M) ((M)->top != 0) 20699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- system alloc setup ------------------------- */ 20719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Operations on mflags */ 20739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) 20759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) 20769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) 20779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) 20799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) 20809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) 20819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) 20839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) 20849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_lock(M,L)\ 20869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((M)->mflags = (L)?\ 20879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((M)->mflags | USE_LOCK_BIT) :\ 20889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((M)->mflags & ~USE_LOCK_BIT)) 20899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* page-align a size */ 20919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define page_align(S)\ 20929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE)) 20939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* granularity-align a size */ 20959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define granularity_align(S)\ 20969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE)) 20979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 20989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_page_aligned(S)\ 20999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) 21009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_granularity_aligned(S)\ 21019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) 21029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* True if segment S holds address A */ 21049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define segment_holds(S, A)\ 21059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) 21069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Return segment holding given address */ 21089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic msegmentptr segment_holding(mstate m, char* addr) { 21099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = &m->seg; 21109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) { 21119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (addr >= sp->base && addr < sp->base + sp->size) 21129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return sp; 21139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((sp = sp->next) == 0) 21149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 21159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 21169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 21179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Return true if segment contains a segment link */ 21199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int has_segment_link(mstate m, msegmentptr ss) { 21209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = &m->seg; 21219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) { 21229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) 21239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 21249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((sp = sp->next) == 0) 21259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 21269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 21279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 21289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MORECORE_CANNOT_TRIM 21309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define should_trim(M,s) ((s) > (M)->trim_check) 21319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MORECORE_CANNOT_TRIM */ 21329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define should_trim(M,s) (0) 21339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE_CANNOT_TRIM */ 21349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 21369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall TOP_FOOT_SIZE is padding at the end of a segment, including space 21379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that may be needed to place segment records and fenceposts when new 21389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall noncontiguous segments are added. 21399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 21409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define TOP_FOOT_SIZE\ 21419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) 21429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------------- Hooks -------------------------------- */ 21459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 21479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PREACTION should be defined to return 0 on success, and nonzero on 21489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall failure. If you are not using locking, you can redefine these to do 21499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall anything you like. 21509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 21519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_LOCKS 21539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Ensure locks are initialized */ 21559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams()) 21569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define PREACTION(M) ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) 21589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } 21599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* USE_LOCKS */ 21609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef PREACTION 21629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define PREACTION(M) (0) 21639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* PREACTION */ 21649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef POSTACTION 21669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define POSTACTION(M) 21679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* POSTACTION */ 21689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_LOCKS */ 21709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 21729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. 21739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION is triggered on detected bad frees and 21749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall reallocs. The argument p is an address that might have triggered the 21759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fault. It is ignored by the two predefined actions, but might be 21769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall useful in custom actions that try to help diagnose errors. 21779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 21789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if PROCEED_ON_ERROR 21809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* A count of the number of corruption errors causing resets */ 21829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint malloc_corruption_error_count; 21839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* default corruption action */ 21859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void reset_on_error(mstate m); 21869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) 21889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USAGE_ERROR_ACTION(m, p) 21899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* PROCEED_ON_ERROR */ 21919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef CORRUPTION_ERROR_ACTION 21939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CORRUPTION_ERROR_ACTION(m) ABORT 21949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* CORRUPTION_ERROR_ACTION */ 21959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 21969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef USAGE_ERROR_ACTION 21979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define USAGE_ERROR_ACTION(m,p) ABORT 21989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USAGE_ERROR_ACTION */ 21999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* PROCEED_ON_ERROR */ 22019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- Debugging setup ---------------------------- */ 22039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ! DEBUG 22059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_free_chunk(M,P) 22079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_inuse_chunk(M,P) 22089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_malloced_chunk(M,P,N) 22099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_mmapped_chunk(M,P) 22109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_malloc_state(M) 22119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_top_chunk(M,P) 22129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* DEBUG */ 22149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_free_chunk(M,P) do_check_free_chunk(M,P) 22159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) 22169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_top_chunk(M,P) do_check_top_chunk(M,P) 22179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) 22189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) 22199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define check_malloc_state(M) do_check_malloc_state(M) 22209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_any_chunk(mstate m, mchunkptr p); 22229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_top_chunk(mstate m, mchunkptr p); 22239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_mmapped_chunk(mstate m, mchunkptr p); 22249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_inuse_chunk(mstate m, mchunkptr p); 22259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_free_chunk(mstate m, mchunkptr p); 22269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_malloced_chunk(mstate m, void* mem, size_t s); 22279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_tree(mstate m, tchunkptr t); 22289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_treebin(mstate m, bindex_t i); 22299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_smallbin(mstate m, bindex_t i); 22309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_malloc_state(mstate m); 22319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int bin_find(mstate m, mchunkptr x); 22329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic size_t traverse_and_check(mstate m); 22339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEBUG */ 22349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ---------------------------- Indexing Bins ---------------------------- */ 22369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) 22389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define small_index(s) ((s) >> SMALLBIN_SHIFT) 22399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define small_index2size(i) ((i) << SMALLBIN_SHIFT) 22409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) 22419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* addressing by index. See above about smallbin repositioning */ 22439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) 22449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define treebin_at(M,i) (&((M)->treebins[i])) 22459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* assign tree index for size S to variable I */ 22479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(__GNUC__) && defined(i386) 22489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define compute_tree_index(S, I)\ 22499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{\ 22509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t X = S >> TREEBIN_SHIFT;\ 22519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (X == 0)\ 22529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = 0;\ 22539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (X > 0xFFFF)\ 22549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = NTREEBINS-1;\ 22559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 22569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int K;\ 22579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm" (X));\ 22589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ 22599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 22609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 22619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* GNUC */ 22629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define compute_tree_index(S, I)\ 22639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{\ 22649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t X = S >> TREEBIN_SHIFT;\ 22659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (X == 0)\ 22669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = 0;\ 22679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (X > 0xFFFF)\ 22689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = NTREEBINS-1;\ 22699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 22709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int Y = (unsigned int)X;\ 22719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int N = ((Y - 0x100) >> 16) & 8;\ 22729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ 22739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K;\ 22749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ 22759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall K = 14 - N + ((Y <<= K) >> 15);\ 22769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ 22779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 22789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 22799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* GNUC */ 22809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bit representing maximum resolved size in a treebin at i */ 22829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define bit_for_tree_index(i) \ 22839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) 22849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Shift placing maximum resolved bit in a treebin at i as sign bit */ 22869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define leftshift_for_tree_index(i) \ 22879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((i == NTREEBINS-1)? 0 : \ 22889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) 22899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The size of the smallest chunk held in bin with index i */ 22919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define minsize_for_tree_index(i) \ 22929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ 22939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) 22949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------ Operations on bin maps ----------------------- */ 22979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 22989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* bit corresponding to given index */ 22999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define idx2bit(i) ((binmap_t)(1) << (i)) 23009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Mark/Clear bits with given index */ 23029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) 23039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) 23049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) 23059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) 23079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) 23089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) 23099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* index corresponding to given bit */ 23119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(__GNUC__) && defined(i386) 23139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define compute_bit2idx(X, I)\ 23149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{\ 23159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int J;\ 23169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\ 23179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = (bindex_t)J;\ 23189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 23199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* GNUC */ 23219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_BUILTIN_FFS 23229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define compute_bit2idx(X, I) I = ffs(X)-1 23239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* USE_BUILTIN_FFS */ 23259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define compute_bit2idx(X, I)\ 23269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{\ 23279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int Y = X - 1;\ 23289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int K = Y >> (16-4) & 16;\ 23299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int N = K; Y >>= K;\ 23309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K = Y >> (8-3) & 8; Y >>= K;\ 23319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K = Y >> (4-2) & 4; Y >>= K;\ 23329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K = Y >> (2-1) & 2; Y >>= K;\ 23339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall N += K = Y >> (1-0) & 1; Y >>= K;\ 23349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall I = (bindex_t)(N + Y);\ 23359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 23369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_BUILTIN_FFS */ 23379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* GNUC */ 23389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* isolate the least set bit of a bitmap */ 23409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define least_bit(x) ((x) & -(x)) 23419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* mask with all bits to left of least bit of x on */ 23439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define left_bits(x) ((x<<1) | -(x<<1)) 23449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* mask with all bits to left of or equal to least bit of x on */ 23469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define same_or_left_bits(x) ((x) | -(x)) 23479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------- Runtime Check Support ------------------------- */ 23509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 23529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall For security, the main invariant is that malloc/free/etc never 23539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall writes to a static address other than malloc_state, unless static 23549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc_state itself has been corrupted, which cannot occur via 23559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc (because of these checks). In essence this means that we 23569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall believe all pointers, sizes, maps etc held in malloc_state, but 23579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check all of those linked or offsetted from other embedded data 23589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall structures. These checks are interspersed with main code in a way 23599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that tends to minimize their run-time cost. 23609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall When FOOTERS is defined, in addition to range checking, we also 23629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall verify footer fields of inuse chunks, which can be used guarantee 23639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that the mstate controlling malloc/free is intact. This is a 23649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall streamlined version of the approach described by William Robertson 23659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall et al in "Run-time Detection of Heap-based Overflows" LISA'03 23669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall http://www.usenix.org/events/lisa03/tech/robertson.html The footer 23679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of an inuse chunk holds the xor of its mstate and a random seed, 23689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that is checked upon calls to free() and realloc(). This is 23699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (probablistically) unguessable from outside the program, but can be 23709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall computed by any code successfully malloc'ing any chunk, so does not 23719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall itself provide protection against code that has already broken 23729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall security through some other means. Unlike Robertson et al, we 23739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall always dynamically check addresses of all offset chunks (previous, 23749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall next, etc). This turns out to be cheaper than relying on hashes. 23759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 23769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !INSECURE 23789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check if address a is at least as high as any from MORECORE or MMAP */ 23799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) 23809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check if address of next chunk n is higher than base chunk p */ 23819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_next(p, n) ((char*)(p) < (char*)(n)) 23829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check if p has its cinuse bit on */ 23839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_cinuse(p) cinuse(p) 23849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check if p has its pinuse bit on */ 23859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_pinuse(p) pinuse(p) 23869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* !INSECURE */ 23889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_address(M, a) (1) 23899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_next(b, n) (1) 23909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_cinuse(p) (1) 23919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_pinuse(p) (1) 23929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !INSECURE */ 23939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 23949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (FOOTERS && !INSECURE) 23959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check if (alleged) mstate m has expected magic field */ 23969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_magic(M) ((M)->magic == mparams.magic) 23979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* (FOOTERS && !INSECURE) */ 23989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define ok_magic(M) (1) 23999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* (FOOTERS && !INSECURE) */ 24009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* In gcc, use __builtin_expect to minimize impact of checks */ 24039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !INSECURE 24049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if defined(__GNUC__) && __GNUC__ >= 3 24059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RTCHECK(e) __builtin_expect(e, 1) 24069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* GNUC */ 24079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RTCHECK(e) (e) 24089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* GNUC */ 24099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* !INSECURE */ 24109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define RTCHECK(e) (1) 24119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !INSECURE */ 24129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* macros to set up inuse chunks with or without footers */ 24149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !FOOTERS 24169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define mark_inuse_foot(M,p,s) 24189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set cinuse bit and pinuse bit of next chunk */ 24209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_inuse(M,p,s)\ 24219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ 24229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) 24239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ 24259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_inuse_and_pinuse(M,p,s)\ 24269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 24279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) 24289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set size, cinuse and pinuse bit of this chunk */ 24309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ 24319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) 24329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 24349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set foot of inuse chunk to be xor of mstate and seed */ 24369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define mark_inuse_foot(M,p,s)\ 24379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) 24389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define get_mstate_for(p)\ 24409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((mstate)(((mchunkptr)((char*)(p) +\ 24419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (chunksize(p))))->prev_foot ^ mparams.magic)) 24429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_inuse(M,p,s)\ 24449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ 24459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ 24469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_inuse_foot(M,p,s)) 24479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_inuse_and_pinuse(M,p,s)\ 24499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 24509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ 24519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_inuse_foot(M,p,s)) 24529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ 24549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ 24559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_inuse_foot(M, p, s)) 24569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !FOOTERS */ 24589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ---------------------------- setting mparams -------------------------- */ 24609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Initialize mparams */ 24629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int init_mparams(void) { 24639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mparams.page_size == 0) { 24649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t s; 24659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; 24679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; 24689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MORECORE_CONTIGUOUS 24699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; 24709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MORECORE_CONTIGUOUS */ 24719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; 24729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MORECORE_CONTIGUOUS */ 24739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (FOOTERS && !INSECURE) 24759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 24769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if USE_DEV_RANDOM 24779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fd; 24789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned char buf[sizeof(size_t)]; 24799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Try to use /dev/urandom, else fall back on using time */ 24809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && 24819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall read(fd, buf, sizeof(buf)) == sizeof(buf)) { 24829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = *((size_t *) buf); 24839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall close(fd); 24849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 24859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 24869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* USE_DEV_RANDOM */ 24879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = (size_t)(time(0) ^ (size_t)0x55555555U); 24889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s |= (size_t)8U; /* ensure nonzero */ 24909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s &= ~(size_t)7U; /* improve chances of fault for bad values */ 24919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 24929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 24939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* (FOOTERS && !INSECURE) */ 24949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = (size_t)0x58585858U; 24959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* (FOOTERS && !INSECURE) */ 24969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ACQUIRE_MAGIC_INIT_LOCK(); 24979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mparams.magic == 0) { 24989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.magic = s; 24999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up lock for main malloc area */ 25009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall INITIAL_LOCK(&gm->mutex); 25019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gm->mflags = mparams.default_mflags; 25029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 25039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall RELEASE_MAGIC_INIT_LOCK(); 25049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef WIN32 25069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.page_size = malloc_getpagesize; 25079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.granularity = ((DEFAULT_GRANULARITY != 0)? 25089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DEFAULT_GRANULARITY : mparams.page_size); 25099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* WIN32 */ 25109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 25119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SYSTEM_INFO system_info; 25129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall GetSystemInfo(&system_info); 25139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.page_size = system_info.dwPageSize; 25149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.granularity = system_info.dwAllocationGranularity; 25159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 25169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* WIN32 */ 25179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Sanity-check configuration: 25199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t must be unsigned and as wide as pointer type. 25209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ints must be at least 4 bytes. 25219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignment must be at least 8. 25229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Alignment, min chunk size, and page size must all be powers of 2. 25239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 25249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((sizeof(size_t) != sizeof(char*)) || 25259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (MAX_SIZE_T < MIN_CHUNK_SIZE) || 25269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (sizeof(int) < 4) || 25279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (MALLOC_ALIGNMENT < (size_t)8U) || 25289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || 25299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || 25309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) || 25319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((mparams.page_size & (mparams.page_size-SIZE_T_ONE)) != 0)) 25329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ABORT; 25339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 25349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 25359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 25369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* support for mallopt */ 25389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int change_mparam(int param_number, int value) { 25399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t val = (size_t)value; 25409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); 25419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch(param_number) { 25429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case M_TRIM_THRESHOLD: 25439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.trim_threshold = val; 25449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 25459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case M_GRANULARITY: 25469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (val >= mparams.page_size && ((val & (val-1)) == 0)) { 25479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.granularity = val; 25489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 25499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 25509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 25519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 25529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case M_MMAP_THRESHOLD: 25539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mparams.mmap_threshold = val; 25549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 25559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 25569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 25579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 25589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 25599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if DEBUG 25619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------- Debugging Support --------------------------- */ 25629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of any chunk, whether free, inuse, mmapped etc */ 25649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_any_chunk(mstate m, mchunkptr p) { 25659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 25669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(ok_address(m, p)); 25679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 25689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of top chunk */ 25709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_top_chunk(mstate m, mchunkptr p) { 25719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = segment_holding(m, (char*)p); 25729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = chunksize(p); 25739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sp != 0); 25749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 25759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(ok_address(m, p)); 25769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz == m->topsize); 25779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz > 0); 25789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); 25799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(pinuse(p)); 25809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!next_pinuse(p)); 25819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 25829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of (inuse) mmapped chunks */ 25849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_mmapped_chunk(mstate m, mchunkptr p) { 25859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = chunksize(p); 25869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); 25879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_mmapped(p)); 25889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(use_mmap(m)); 25899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); 25909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(ok_address(m, p)); 25919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!is_small(sz)); 25929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); 25939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); 25949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); 25959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 25969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 25979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of inuse chunks */ 25989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_inuse_chunk(mstate m, mchunkptr p) { 25999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_any_chunk(m, p); 26009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(cinuse(p)); 26019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(next_pinuse(p)); 26029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If not pinuse and not mmapped, previous chunk has OK offset */ 26039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); 26049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_mmapped(p)) 26059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_mmapped_chunk(m, p); 26069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 26079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 26089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of free chunks */ 26099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_free_chunk(mstate m, mchunkptr p) { 26109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); 26119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr next = chunk_plus_offset(p, sz); 26129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_any_chunk(m, p); 26139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!cinuse(p)); 26149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!next_pinuse(p)); 26159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert (!is_mmapped(p)); 26169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p != m->dv && p != m->top) { 26179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (sz >= MIN_CHUNK_SIZE) { 26189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((sz & CHUNK_ALIGN_MASK) == 0); 26199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_aligned(chunk2mem(p))); 26209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(next->prev_foot == sz); 26219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(pinuse(p)); 26229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert (next == m->top || cinuse(next)); 26239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(p->fd->bk == p); 26249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(p->bk->fd == p); 26259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else /* markers are always of size SIZE_T_SIZE */ 26279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz == SIZE_T_SIZE); 26289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 26309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 26319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check properties of malloced chunks at the point they are malloced */ 26329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_malloced_chunk(mstate m, void* mem, size_t s) { 26339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) { 26349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(mem); 26359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); 26369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_inuse_chunk(m, p); 26379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((sz & CHUNK_ALIGN_MASK) == 0); 26389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz >= MIN_CHUNK_SIZE); 26399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(sz >= s); 26409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ 26419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); 26429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 26449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 26459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check a tree and its subtrees. */ 26469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_tree(mstate m, tchunkptr t) { 26479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr head = 0; 26489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr u = t; 26499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t tindex = t->index; 26509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = chunksize(t); 26519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t idx; 26529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_tree_index(tsize, idx); 26539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(tindex == idx); 26549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(tsize >= MIN_LARGE_SIZE); 26559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(tsize >= minsize_for_tree_index(idx)); 26569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); 26579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 26589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { /* traverse through chain of same-sized nodes */ 26599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_any_chunk(m, ((mchunkptr)u)); 26609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->index == tindex); 26619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(u) == tsize); 26629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!cinuse(u)); 26639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!next_pinuse(u)); 26649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->fd->bk == u); 26659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->bk->fd == u); 26669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (u->parent == 0) { 26679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[0] == 0); 26689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[1] == 0); 26699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 26719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(head == 0); /* only one node on chain has parent */ 26729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall head = u; 26739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->parent != u); 26749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert (u->parent->child[0] == u || 26759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall u->parent->child[1] == u || 26769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *((tbinptr*)(u->parent)) == u); 26779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (u->child[0] != 0) { 26789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[0]->parent == u); 26799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[0] != u); 26809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_tree(m, u->child[0]); 26819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (u->child[1] != 0) { 26839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[1]->parent == u); 26849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(u->child[1] != u); 26859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_tree(m, u->child[1]); 26869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (u->child[0] != 0 && u->child[1] != 0) { 26889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(u->child[0]) < chunksize(u->child[1])); 26899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 26919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall u = u->fd; 26929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } while (u != t); 26939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(head != 0); 26949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 26959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 26969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check all the chunks in a treebin. */ 26979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_treebin(mstate m, bindex_t i) { 26989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbinptr* tb = treebin_at(m, i); 26999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr t = *tb; 27009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int empty = (m->treemap & (1U << i)) == 0; 27019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (t == 0) 27029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(empty); 27039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!empty) 27049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_tree(m, t); 27059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 27069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 27079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check all the chunks in a smallbin. */ 27089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_smallbin(mstate m, bindex_t i) { 27099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sbinptr b = smallbin_at(m, i); 27109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = b->bk; 27119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int empty = (m->smallmap & (1U << i)) == 0; 27129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == b) 27139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(empty); 27149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!empty) { 27159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (; p != b; p = p->bk) { 27169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size = chunksize(p); 27179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q; 27189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* each chunk claims to be free */ 27199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_free_chunk(m, p); 27209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* chunk belongs in bin */ 27219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(small_index(size) == i); 27229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(p->bk == b || chunksize(p->bk) == chunksize(p)); 27239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* chunk is followed by an inuse chunk */ 27249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q = next_chunk(p); 27259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (q->head != FENCEPOST_HEAD) 27269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_inuse_chunk(m, q); 27279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 27309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 27319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Find x in a bin. Used in other check functions. */ 27329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int bin_find(mstate m, mchunkptr x) { 27339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size = chunksize(x); 27349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_small(size)) { 27359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t sidx = small_index(size); 27369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sbinptr b = smallbin_at(m, sidx); 27379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (smallmap_is_marked(m, sidx)) { 27389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = b; 27399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { 27409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == x) 27419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 27429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } while ((p = p->fd) != b); 27439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 27469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t tidx; 27479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_tree_index(size, tidx); 27489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (treemap_is_marked(m, tidx)) { 27499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr t = *treebin_at(m, tidx); 27509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sizebits = size << leftshift_for_tree_index(tidx); 27519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (t != 0 && chunksize(t) != size) { 27529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; 27539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sizebits <<= 1; 27549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (t != 0) { 27569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr u = t; 27579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { 27589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (u == (tchunkptr)x) 27599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 27609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } while ((u = u->fd) != t); 27619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 27659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 27669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 27679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Traverse each chunk and check it; return total */ 27689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic size_t traverse_and_check(mstate m) { 27699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sum = 0; 27709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_initialized(m)) { 27719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr s = &m->seg; 27729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sum += m->topsize + TOP_FOOT_SIZE; 27739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (s != 0) { 27749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q = align_as_chunk(s->base); 27759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr lastq = 0; 27769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(pinuse(q)); 27779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (segment_holds(s, q) && 27789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q != m->top && q->head != FENCEPOST_HEAD) { 27799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sum += chunksize(q); 27809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cinuse(q)) { 27819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!bin_find(m, q)); 27829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_inuse_chunk(m, q); 27839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 27859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(q == m->dv || bin_find(m, q)); 27869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ 27879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_free_chunk(m, q); 27889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lastq = q; 27909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q = next_chunk(q); 27919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = s->next; 27939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 27959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return sum; 27969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 27979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 27989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Check all properties of malloc_state. */ 27999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void do_check_malloc_state(mstate m) { 28009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 28019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t total; 28029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* check bins */ 28039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < NSMALLBINS; ++i) 28049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_smallbin(m, i); 28059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < NTREEBINS; ++i) 28069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_treebin(m, i); 28079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (m->dvsize != 0) { /* check dv chunk */ 28099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_any_chunk(m, m->dv); 28109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(m->dvsize == chunksize(m->dv)); 28119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(m->dvsize >= MIN_CHUNK_SIZE); 28129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(bin_find(m, m->dv) == 0); 28139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (m->top != 0) { /* check top chunk */ 28169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do_check_top_chunk(m, m->top); 28179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(m->topsize == chunksize(m->top)); 28189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(m->topsize > 0); 28199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(bin_find(m, m->top) == 0); 28209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall total = traverse_and_check(m); 28239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(total <= m->footprint); 28249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(m->footprint <= m->max_footprint); 28259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 28269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEBUG */ 28279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------------- statistics ------------------------------ */ 28299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 28319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic struct mallinfo internal_mallinfo(mstate m) { 28329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 28339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(m)) { 28349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloc_state(m); 28359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_initialized(m)) { 28369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nfree = SIZE_T_ONE; /* top always free */ 28379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t mfree = m->topsize + TOP_FOOT_SIZE; 28389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sum = mfree; 28399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr s = &m->seg; 28409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (s != 0) { 28419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q = align_as_chunk(s->base); 28429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (segment_holds(s, q) && 28439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q != m->top && q->head != FENCEPOST_HEAD) { 28449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = chunksize(q); 28459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sum += sz; 28469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(q)) { 28479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mfree += sz; 28489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ++nfree; 28499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q = next_chunk(q); 28519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = s->next; 28539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.arena = sum; 28569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.ordblks = nfree; 28579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.hblkhd = m->footprint - sum; 28589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.usmblks = m->max_footprint; 28599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.uordblks = m->footprint - mfree; 28609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.fordblks = mfree; 28619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nm.keepcost = m->topsize; 28629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 28659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return nm; 28679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 28689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !NO_MALLINFO */ 28699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void internal_malloc_stats(mstate m) { 28719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(m)) { 28729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t maxfp = 0; 28739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t fp = 0; 28749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t used = 0; 28759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloc_state(m); 28769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_initialized(m)) { 28779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr s = &m->seg; 28789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall maxfp = m->max_footprint; 28799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fp = m->footprint; 28809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used = fp - (m->topsize + TOP_FOOT_SIZE); 28819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (s != 0) { 28839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q = align_as_chunk(s->base); 28849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (segment_holds(s, q) && 28859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q != m->top && q->head != FENCEPOST_HEAD) { 28869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(q)) 28879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used -= chunksize(q); 28889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q = next_chunk(q); 28899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s = s->next; 28919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 28939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 28949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef LACKS_STDIO_H 28959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); 28969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); 28979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); 28989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 28999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 29019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 29029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 29039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------- Operations on smallbins ----------------------- */ 29059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Various forms of linking and unlinking are defined as macros. Even 29089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the ones for trees, which are very long but have very short typical 29099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall paths. This is ugly but reduces reliance on inlining support of 29109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compilers. 29119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 29129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Link a free chunk into a smallbin */ 29149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define insert_small_chunk(M, P, S) {\ 29159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t I = small_index(S);\ 29169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr B = smallbin_at(M, I);\ 29179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr F = B;\ 29189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(S >= MIN_CHUNK_SIZE);\ 29199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!smallmap_is_marked(M, I))\ 29209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_smallmap(M, I);\ 29219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (RTCHECK(ok_address(M, B->fd)))\ 29229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall F = B->fd;\ 29239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 29249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 29259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall B->fd = P;\ 29279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall F->bk = P;\ 29289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall P->fd = F;\ 29299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall P->bk = B;\ 29309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 29319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Unlink a chunk from a smallbin */ 29339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define unlink_small_chunk(M, P, S) {\ 29349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr F = P->fd;\ 29359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr B = P->bk;\ 29369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t I = small_index(S);\ 29379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(P != B);\ 29389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(P != F);\ 29399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(P) == small_index2size(I));\ 29409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (F == B)\ 29419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall clear_smallmap(M, I);\ 29429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ 29439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (B == smallbin_at(M,I) || ok_address(M, B)))) {\ 29449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall F->bk = B;\ 29459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall B->fd = F;\ 29469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 29489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 29499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 29519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Unlink the first chunk from a smallbin */ 29539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define unlink_first_small_chunk(M, B, P, I) {\ 29549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr F = P->fd;\ 29559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(P != B);\ 29569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(P != F);\ 29579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(P) == small_index2size(I));\ 29589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (B == F)\ 29599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall clear_smallmap(M, I);\ 29609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (RTCHECK(ok_address(M, F))) {\ 29619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall B->fd = F;\ 29629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall F->bk = B;\ 29639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 29659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 29669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 29689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Replace dv node, binning the old one */ 29709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Used only when dvsize known to be small */ 29719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define replace_dv(M, P, S) {\ 29729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t DVS = M->dvsize;\ 29739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (DVS != 0) {\ 29749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr DV = M->dv;\ 29759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_small(DVS));\ 29769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_small_chunk(M, DV, DVS);\ 29779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall M->dvsize = S;\ 29799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall M->dv = P;\ 29809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 29819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------- Operations on trees ------------------------- */ 29839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Insert chunk into tree */ 29859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define insert_large_chunk(M, X, S) {\ 29869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbinptr* H;\ 29879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t I;\ 29889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_tree_index(S, I);\ 29899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall H = treebin_at(M, I);\ 29909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->index = I;\ 29919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->child[0] = X->child[1] = 0;\ 29929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!treemap_is_marked(M, I)) {\ 29939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_treemap(M, I);\ 29949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *H = X;\ 29959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->parent = (tchunkptr)H;\ 29969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->fd = X->bk = X;\ 29979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 29989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 29999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr T = *H;\ 30009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t K = S << leftshift_for_tree_index(I);\ 30019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) {\ 30029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (chunksize(T) != S) {\ 30039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ 30049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall K <<= 1;\ 30059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (*C != 0)\ 30069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall T = *C;\ 30079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (RTCHECK(ok_address(M, C))) {\ 30089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *C = X;\ 30099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->parent = T;\ 30109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->fd = X->bk = X;\ 30119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break;\ 30129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 30159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break;\ 30169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr F = T->fd;\ 30209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ 30219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall T->fd = F->bk = X;\ 30229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->fd = F;\ 30239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->bk = T;\ 30249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall X->parent = 0;\ 30259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break;\ 30269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 30299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break;\ 30309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 30359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 30369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 30379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Unlink steps: 30389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 30399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1. If x is a chained node, unlink it from its same-sized fd/bk links 30409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and choose its bk node as its replacement. 30419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2. If x was the last node of its size, but not a leaf node, it must 30429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall be replaced with a leaf node (not merely one with an open left or 30439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall right), to make sure that lefts and rights of descendents 30449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall correspond properly to bit masks. We use the rightmost descendent 30459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall of x. We could use any other leaf, but this is easy to locate and 30469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tends to counteract removal of leftmosts elsewhere, and so keeps 30479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall paths shorter than minimally guaranteed. This doesn't loop much 30489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall because on average a node in a tree is near the bottom. 30499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3. If x is the base of a chain (i.e., has parent links) relink 30509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall x's parent and children to x's replacement (or null if none). 30519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 30529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 30539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define unlink_large_chunk(M, X) {\ 30549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr XP = X->parent;\ 30559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr R;\ 30569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (X->bk != X) {\ 30579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr F = X->fd;\ 30589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R = X->bk;\ 30599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, F))) {\ 30609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall F->bk = R;\ 30619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R->fd = F;\ 30629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 30659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr* RP;\ 30699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (((R = *(RP = &(X->child[1]))) != 0) ||\ 30709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ((R = *(RP = &(X->child[0]))) != 0)) {\ 30719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr* CP;\ 30729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ((*(CP = &(R->child[1])) != 0) ||\ 30739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (*(CP = &(R->child[0])) != 0)) {\ 30749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R = *(RP = CP);\ 30759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, RP)))\ 30779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *RP = 0;\ 30789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else {\ 30799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 30809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (XP != 0) {\ 30849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbinptr* H = treebin_at(M, X->index);\ 30859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (X == *H) {\ 30869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((*H = R) == 0) \ 30879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall clear_treemap(M, X->index);\ 30889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (RTCHECK(ok_address(M, XP))) {\ 30909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (XP->child[0] == X) \ 30919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall XP->child[0] = R;\ 30929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else \ 30939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall XP->child[1] = R;\ 30949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 30959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else\ 30969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 30979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (R != 0) {\ 30989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, R))) {\ 30999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr C0, C1;\ 31009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R->parent = XP;\ 31019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((C0 = X->child[0]) != 0) {\ 31029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, C0))) {\ 31039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R->child[0] = C0;\ 31049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall C0->parent = R;\ 31059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else\ 31079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 31089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((C1 = X->child[1]) != 0) {\ 31109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(M, C1))) {\ 31119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall R->child[1] = C1;\ 31129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall C1->parent = R;\ 31139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else\ 31159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 31169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else\ 31199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(M);\ 31209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall }\ 31229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 31239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Relays to large vs small bin operations */ 31259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define insert_chunk(M, P, S)\ 31279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_small(S)) insert_small_chunk(M, P, S)\ 31289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } 31299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define unlink_chunk(M, P, S)\ 31319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_small(S)) unlink_small_chunk(M, P, S)\ 31329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } 31339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Relays to internal calls to malloc/free from realloc, memalign etc */ 31369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ONLY_MSPACES 31389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_malloc(m, b) mspace_malloc(m, b) 31399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_free(m, mem) mspace_free(m,mem); 31409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* ONLY_MSPACES */ 31419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MSPACES 31429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_malloc(m, b)\ 31439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (m == gm)? dlmalloc(b) : mspace_malloc(m, b) 31449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_free(m, mem)\ 31459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (m == gm) dlfree(mem); else mspace_free(m,mem); 31469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* MSPACES */ 31479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_malloc(m, b) dlmalloc(b) 31489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define internal_free(m, mem) dlfree(mem) 31499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MSPACES */ 31509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* ONLY_MSPACES */ 31519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------- Direct-mmapping chunks ----------------------- */ 31539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 31559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Directly mmapped chunks are set up with an offset to the start of 31569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the mmapped region stored in the prev_foot field of the chunk. This 31579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allows reconstruction of the required argument to MUNMAP when freed, 31589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and also allows adjustment of the returned chunk to meet alignment 31599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall requirements (especially in memalign). There is also enough space 31609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain 31619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the PINUSE bit so frees can be checked. 31629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 31639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Malloc using mmap */ 31659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* mmap_alloc(mstate m, size_t nb) { 31669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); 31679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mmsize > nb) { /* Check for wrap around 0 */ 31689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* mm = (char*)(DIRECT_MMAP(mmsize)); 31699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mm != CMFAIL) { 31709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t offset = align_offset(chunk2mem(mm)); 31719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = mmsize - offset - MMAP_FOOT_PAD; 31729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = (mchunkptr)(mm + offset); 31739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p->prev_foot = offset | IS_MMAPPED_BIT; 31749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (p)->head = (psize|CINUSE_BIT); 31759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_inuse_foot(m, p, psize); 31769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; 31779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; 31789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mm < m->least_addr) 31809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->least_addr = mm; 31819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((m->footprint += mmsize) > m->max_footprint) 31829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->max_footprint = m->footprint; 31839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_aligned(chunk2mem(p))); 31849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_mmapped_chunk(m, p); 31859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(p); 31869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 31879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 31889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 31899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 31909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 31919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Realloc using mmap */ 31929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { 31939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t oldsize = chunksize(oldp); 31949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_small(nb)) /* Can't shrink mmap regions below small size */ 31959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 31969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Keep old chunk if big enough but not too big */ 31979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (oldsize >= nb + SIZE_T_SIZE && 31989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (oldsize - nb) <= (mparams.granularity << 1)) 31999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return oldp; 32009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 32019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; 32029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; 32039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES + 32049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CHUNK_ALIGN_MASK); 32059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* cp = (char*)CALL_MREMAP((char*)oldp - offset, 32069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall oldmmsize, newmmsize, 1); 32079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cp != CMFAIL) { 32089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr newp = (mchunkptr)(cp + offset); 32099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = newmmsize - offset - MMAP_FOOT_PAD; 32109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp->head = (psize|CINUSE_BIT); 32119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mark_inuse_foot(m, newp, psize); 32129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; 32139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; 32149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cp < m->least_addr) 32169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->least_addr = cp; 32179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) 32189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->max_footprint = m->footprint; 32199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_mmapped_chunk(m, newp); 32209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return newp; 32219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 32229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 32239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 32249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 32259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- mspace management -------------------------- */ 32279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Initialize top chunk and its size */ 32299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void init_top(mstate m, mchunkptr p, size_t psize) { 32309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Ensure alignment */ 32319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t offset = align_offset(chunk2mem(p)); 32329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = (mchunkptr)((char*)p + offset); 32339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize -= offset; 32349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->top = p; 32369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->topsize = psize; 32379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p->head = psize | PINUSE_BIT; 32389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* set size of fake trailing chunk holding overhead space only once */ 32399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; 32409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->trim_check = mparams.trim_threshold; /* reset on each update */ 32419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 32429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Initialize bins for a new mstate that is otherwise zeroed out */ 32449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void init_bins(mstate m) { 32459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Establish circular links for smallbins */ 32469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 32479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < NSMALLBINS; ++i) { 32489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sbinptr bin = smallbin_at(m,i); 32499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bin->fd = bin->bk = bin; 32509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 32519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 32529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if PROCEED_ON_ERROR 32549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* default corruption action */ 32569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void reset_on_error(mstate m) { 32579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 32589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ++malloc_corruption_error_count; 32599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Reinitialize fields to forget about all memory */ 32609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->smallbins = m->treebins = 0; 32619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->dvsize = m->topsize = 0; 32629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.base = 0; 32639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.size = 0; 32649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.next = 0; 32659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->top = m->dv = 0; 32669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < NTREEBINS; ++i) 32679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *treebin_at(m, i) = 0; 32689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_bins(m); 32699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 32709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* PROCEED_ON_ERROR */ 32719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Allocate chunk and prepend remainder with chunk in successor base. */ 32739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* prepend_alloc(mstate m, char* newbase, char* oldbase, 32749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nb) { 32759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = align_as_chunk(newbase); 32769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr oldfirst = align_as_chunk(oldbase); 32779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = (char*)oldfirst - (char*)p; 32789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q = chunk_plus_offset(p, nb); 32799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t qsize = psize - nb; 32809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, p, nb); 32819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((char*)oldfirst > (char*)q); 32839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(pinuse(oldfirst)); 32849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(qsize >= MIN_CHUNK_SIZE); 32859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 32869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* consolidate remainder with first chunk of old base */ 32879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (oldfirst == m->top) { 32889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = m->topsize += qsize; 32899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->top = q; 32909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall q->head = tsize | PINUSE_BIT; 32919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(m, q); 32929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 32939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (oldfirst == m->dv) { 32949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dsize = m->dvsize += qsize; 32959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->dv = q; 32969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(q, dsize); 32979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 32989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 32999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(oldfirst)) { 33009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nsize = chunksize(oldfirst); 33019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_chunk(m, oldfirst, nsize); 33029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall oldfirst = chunk_plus_offset(oldfirst, nsize); 33039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall qsize += nsize; 33049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 33059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(q, qsize, oldfirst); 33069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_chunk(m, q, qsize); 33079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_free_chunk(m, q); 33089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 33099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(m, chunk2mem(p), nb); 33119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(p); 33129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 33139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Add a segment to hold a new noncontiguous region */ 33169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { 33179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Determine locations and sizes of segment, fenceposts, old top */ 33189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* old_top = (char*)m->top; 33199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr oldsp = segment_holding(m, old_top); 33209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* old_end = oldsp->base + oldsp->size; 33219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t ssize = pad_request(sizeof(struct malloc_segment)); 33229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); 33239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t offset = align_offset(chunk2mem(rawsp)); 33249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* asp = rawsp + offset; 33259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; 33269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr sp = (mchunkptr)csp; 33279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr ss = (msegmentptr)(chunk2mem(sp)); 33289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr tnext = chunk_plus_offset(sp, ssize); 33299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = tnext; 33309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int nfences = 0; 33319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* reset top to new space */ 33339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); 33349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up segment record */ 33369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(is_aligned(ss)); 33379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); 33389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *ss = m->seg; /* Push current record */ 33399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.base = tbase; 33409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.size = tsize; 33419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.sflags = mmapped; 33429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.next = ss; 33439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Insert trailing fenceposts */ 33459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) { 33469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); 33479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p->head = FENCEPOST_HEAD; 33489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ++nfences; 33499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((char*)(&(nextp->head)) < old_end) 33509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = nextp; 33519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 33529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 33539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 33549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(nfences >= 2); 33559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Insert the rest of old top into a bin as an ordinary free chunk */ 33579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (csp != old_top) { 33589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr q = (mchunkptr)old_top; 33599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = csp - old_top; 33609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr tn = chunk_plus_offset(q, psize); 33619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(q, psize, tn); 33629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_chunk(m, q, psize); 33639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 33649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(m, m->top); 33669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 33679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- System allocation -------------------------- */ 33699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get memory from system using MORECORE or MMAP */ 33719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* sys_alloc(mstate m, size_t nb) { 33729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* tbase = CMFAIL; 33739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = 0; 33749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t mmap_flag = 0; 33759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); 33779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Directly map large chunks */ 33799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_mmap(m) && nb >= mparams.mmap_threshold) { 33809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem = mmap_alloc(m, nb); 33819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) 33829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mem; 33839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 33849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 33859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 33869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Try getting memory in any of three ways (in most-preferred to 33879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall least-preferred order): 33889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1. A call to MORECORE that can normally contiguously extend memory. 33899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or 33909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall or main space is mmapped or a previous contiguous call failed) 33919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2. A call to MMAP new space (disabled if not HAVE_MMAP). 33929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Note that under the default settings, if MORECORE is unable to 33939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fulfill a request, and HAVE_MMAP is true, then mmap is 33949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall used as a noncontiguous system allocator. This is a useful backup 33959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall strategy for systems with holes in address spaces -- in this case 33969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sbrk cannot contiguously expand the heap, but mmap may be able to 33979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall find space. 33989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3. A call to MORECORE that cannot usually contiguously extend memory. 33999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (disabled if not HAVE_MORECORE) 34009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 34019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { 34039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* br = CMFAIL; 34049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); 34059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t asize = 0; 34069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ACQUIRE_MORECORE_LOCK(); 34079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ss == 0) { /* First time through or recovery */ 34099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* base = (char*)CALL_MORECORE(0); 34109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (base != CMFAIL) { 34119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); 34129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Adjust to end on a page boundary */ 34139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!is_page_aligned(base)) 34149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall asize += (page_align((size_t)base) - (size_t)base); 34159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Can't call MORECORE if size is negative when treated as signed */ 34169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (asize < HALF_MAX_SIZE_T && 34179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (br = (char*)(CALL_MORECORE(asize))) == base) { 34189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbase = base; 34199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tsize = asize; 34209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 34249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Subtract out existing available top space from MORECORE request. */ 34259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); 34269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Use mem here only if it did continuously extend old space */ 34279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (asize < HALF_MAX_SIZE_T && 34289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { 34299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbase = br; 34309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tsize = asize; 34319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tbase == CMFAIL) { /* Cope with partial failure */ 34359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (br != CMFAIL) { /* Try to use/extend the space we did get */ 34369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (asize < HALF_MAX_SIZE_T && 34379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { 34389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t esize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE - asize); 34399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (esize < HALF_MAX_SIZE_T) { 34409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* end = (char*)CALL_MORECORE(esize); 34419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (end != CMFAIL) 34429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall asize += esize; 34439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* Can't use; try to release */ 34449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall end = (char*)CALL_MORECORE(-asize); 34459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall br = CMFAIL; 34469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (br != CMFAIL) { /* Use the space we did get */ 34519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbase = br; 34529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tsize = asize; 34539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 34559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall disable_contiguous(m); /* Don't try contiguous path in the future */ 34569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall RELEASE_MORECORE_LOCK(); 34599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ 34629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t req = nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE; 34639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = granularity_align(req); 34649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize > nb) { /* Fail if wraps around zero */ 34659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* mp = (char*)(CALL_MMAP(rsize)); 34669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mp != CMFAIL) { 34679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbase = mp; 34689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tsize = rsize; 34699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mmap_flag = IS_MMAPPED_BIT; 34709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ 34759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); 34769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (asize < HALF_MAX_SIZE_T) { 34779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* br = CMFAIL; 34789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* end = CMFAIL; 34799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ACQUIRE_MORECORE_LOCK(); 34809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall br = (char*)(CALL_MORECORE(asize)); 34819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall end = (char*)(CALL_MORECORE(0)); 34829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall RELEASE_MORECORE_LOCK(); 34839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (br != CMFAIL && end != CMFAIL && br < end) { 34849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t ssize = end - br; 34859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ssize > nb + TOP_FOOT_SIZE) { 34869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tbase = br; 34879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tsize = ssize; 34889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 34929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tbase != CMFAIL) { 34949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((m->footprint += tsize) > m->max_footprint) 34969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->max_footprint = m->footprint; 34979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 34989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!is_initialized(m)) { /* first-time initialization */ 34999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.base = m->least_addr = tbase; 35009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.size = tsize; 35019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.sflags = mmap_flag; 35029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->magic = mparams.magic; 35039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_bins(m); 35049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_global(m)) 35059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); 35069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 35079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Offset top by embedded malloc_state */ 35089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr mn = next_chunk(mem2chunk(m)); 35099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); 35109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 35139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 35149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Try to merge with an existing segment */ 35159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = &m->seg; 35169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (sp != 0 && tbase != sp->base + sp->size) 35179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = sp->next; 35189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (sp != 0 && 35199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall !is_extern_segment(sp) && 35209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && 35219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall segment_holds(sp, m->top)) { /* append */ 35229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->size += tsize; 35239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, m->top, m->topsize + tsize); 35249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 35269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tbase < m->least_addr) 35279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->least_addr = tbase; 35289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = &m->seg; 35299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (sp != 0 && sp->base != tbase + tsize) 35309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = sp->next; 35319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (sp != 0 && 35329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall !is_extern_segment(sp) && 35339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { 35349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* oldbase = sp->base; 35359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->base = tbase; 35369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->size += tsize; 35379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return prepend_alloc(m, tbase, oldbase, nb); 35389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 35409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall add_segment(m, tbase, tsize, mmap_flag); 35419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 35449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (nb < m->topsize) { /* Allocate from new or extended top space */ 35459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = m->topsize -= nb; 35469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = m->top; 35479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = m->top = chunk_plus_offset(p, nb); 35489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r->head = rsize | PINUSE_BIT; 35499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, p, nb); 35509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(m, m->top); 35519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(m, chunk2mem(p), nb); 35529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(p); 35539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 35569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLOC_FAILURE_ACTION; 35579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 35589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 35599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 35609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------- system deallocation -------------------------- */ 35619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 35629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Unmap and unlink any mmapped segments that don't contain used chunks */ 35639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic size_t release_unused_segments(mstate m) { 35649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t released = 0; 35659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr pred = &m->seg; 35669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = pred->next; 35679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (sp != 0) { 35689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* base = sp->base; 35699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size = sp->size; 35709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr next = sp->next; 35719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { 35729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = align_as_chunk(base); 35739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = chunksize(p); 35749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Can unmap if first chunk holds entire segment and not pinned */ 35759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { 35769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr tp = (tchunkptr)p; 35779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(segment_holds(sp, (char*)sp)); 35789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == m->dv) { 35799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->dv = 0; 35809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->dvsize = 0; 35819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 35839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_large_chunk(m, tp); 35849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CALL_MUNMAP(base, size) == 0) { 35869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall released += size; 35879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->footprint -= size; 35889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* unlink obsoleted record */ 35899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = pred; 35909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->next = next; 35919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* back out if cannot unmap */ 35939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_large_chunk(m, tp, psize); 35949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 35979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pred = sp; 35989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = next; 35999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return released; 36019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 36029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int sys_trim(mstate m, size_t pad) { 36049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t released = 0; 36059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (pad < MAX_REQUEST && is_initialized(m)) { 36069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ 36079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (m->topsize > pad) { 36099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Shrink top space in granularity-size units, keeping at least one */ 36109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t unit = mparams.granularity; 36119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - 36129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SIZE_T_ONE) * unit; 36139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = segment_holding(m, (char*)m->top); 36149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!is_extern_segment(sp)) { 36169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_mmapped_segment(sp)) { 36179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (HAVE_MMAP && 36189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->size >= extra && 36199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall !has_segment_link(m, sp)) { /* can't shrink if pinned */ 36209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t newsize = sp->size - extra; 36219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Prefer mremap, fall back to munmap */ 36229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || 36239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { 36249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall released = extra; 36259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (HAVE_MORECORE) { 36299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ 36309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; 36319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ACQUIRE_MORECORE_LOCK(); 36329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 36339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Make sure end of memory is where we last set it. */ 36349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* old_br = (char*)(CALL_MORECORE(0)); 36359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (old_br == sp->base + sp->size) { 36369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* rel_br = (char*)(CALL_MORECORE(-extra)); 36379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* new_br = (char*)(CALL_MORECORE(0)); 36389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rel_br != CMFAIL && new_br < old_br) 36399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall released = old_br - new_br; 36409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall RELEASE_MORECORE_LOCK(); 36439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (released != 0) { 36479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp->size -= released; 36489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->footprint -= released; 36499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, m->top, m->topsize - released); 36509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(m, m->top); 36519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Unmap any unused mmapped segments */ 36559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (HAVE_MMAP) 36569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall released += release_unused_segments(m); 36579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* On failure, disable autotrim to avoid repeated failed future calls */ 36599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (released == 0) 36609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->trim_check = MAX_SIZE_T; 36619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (released != 0)? 1 : 0; 36649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 36659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ---------------------------- malloc support --------------------------- */ 36679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* allocate a large request from the best fitting chunk in a treebin */ 36699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* tmalloc_large(mstate m, size_t nb) { 36709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr v = 0; 36719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = -nb; /* Unsigned negation */ 36729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr t; 36739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t idx; 36749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_tree_index(nb, idx); 36759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 36769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((t = *treebin_at(m, idx)) != 0) { 36779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Traverse tree for this bin looking for node with size == nb */ 36789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sizebits = nb << leftshift_for_tree_index(idx); 36799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr rst = 0; /* The deepest untaken right subtree */ 36809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (;;) { 36819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr rt; 36829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t trem = chunksize(t) - nb; 36839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (trem < rsize) { 36849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v = t; 36859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((rsize = trem) == 0) 36869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 36879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rt = t->child[1]; 36899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; 36909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rt != 0 && rt != t) 36919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rst = rt; 36929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (t == 0) { 36939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall t = rst; /* set t to least subtree holding sizes > nb */ 36949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 36959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sizebits <<= 1; 36979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 36999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ 37019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; 37029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (leftbits != 0) { 37039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 37049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leastbit = least_bit(leftbits); 37059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_bit2idx(leastbit, i); 37069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall t = *treebin_at(m, i); 37079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (t != 0) { /* find smallest of tree or subtree */ 37119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t trem = chunksize(t) - nb; 37129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (trem < rsize) { 37139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rsize = trem; 37149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v = t; 37159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall t = leftmost_child(t); 37179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If dv is a better fit, return 0 so malloc will use it */ 37209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { 37219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(m, v))) { /* split */ 37229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = chunk_plus_offset(v, nb); 37239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(v) == rsize + nb); 37249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_next(v, r))) { 37259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_large_chunk(m, v); 37269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize < MIN_CHUNK_SIZE) 37279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(m, v, (rsize + nb)); 37289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 37299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, v, nb); 37309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 37319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_chunk(m, r, rsize); 37329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(v); 37349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(m); 37379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 37399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 37409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* allocate a small request from the best fitting chunk in a treebin */ 37429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* tmalloc_small(mstate m, size_t nb) { 37439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tchunkptr t, v; 37449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize; 37459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 37469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leastbit = least_bit(m->treemap); 37479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_bit2idx(leastbit, i); 37489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v = t = *treebin_at(m, i); 37509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rsize = chunksize(t) - nb; 37519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ((t = leftmost_child(t)) != 0) { 37539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t trem = chunksize(t) - nb; 37549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (trem < rsize) { 37559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rsize = trem; 37569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v = t; 37579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(m, v))) { 37619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = chunk_plus_offset(v, nb); 37629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(v) == rsize + nb); 37639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_next(v, r))) { 37649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_large_chunk(m, v); 37659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize < MIN_CHUNK_SIZE) 37669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(m, v, (rsize + nb)); 37679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 37689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, v, nb); 37699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 37709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall replace_dv(m, r, rsize); 37719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(v); 37739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CORRUPTION_ERROR_ACTION(m); 37779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 37789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 37799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* --------------------------- realloc support --------------------------- */ 37819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* internal_realloc(mstate m, void* oldmem, size_t bytes) { 37839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes >= MAX_REQUEST) { 37849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLOC_FAILURE_ACTION; 37859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 37869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 37879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(m)) { 37889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr oldp = mem2chunk(oldmem); 37899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t oldsize = chunksize(oldp); 37909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr next = chunk_plus_offset(oldp, oldsize); 37919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr newp = 0; 37929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* extra = 0; 37939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Try to either shrink or extend into top. Else malloc-copy-free */ 37959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 37969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && 37979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ok_next(oldp, next) && ok_pinuse(next))) { 37989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nb = request2size(bytes); 37999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_mmapped(oldp)) 38009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp = mmap_resize(m, oldp, nb); 38019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (oldsize >= nb) { /* already big enough */ 38029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = oldsize - nb; 38039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp = oldp; 38049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize >= MIN_CHUNK_SIZE) { 38059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr remainder = chunk_plus_offset(newp, nb); 38069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, newp, nb); 38079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, remainder, rsize); 38089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall extra = chunk2mem(remainder); 38099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (next == m->top && oldsize + m->topsize > nb) { 38129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Expand into top */ 38139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t newsize = oldsize + m->topsize; 38149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t newtopsize = newsize - nb; 38159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr newtop = chunk_plus_offset(oldp, nb); 38169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, oldp, nb); 38179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newtop->head = newtopsize |PINUSE_BIT; 38189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->top = newtop; 38199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->topsize = newtopsize; 38209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp = oldp; 38219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 38249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(m, oldmem); 38259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 38269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 38279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 38309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (newp != 0) { 38329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (extra != 0) { 38339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_free(m, extra); 38349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(m, newp); 38369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(newp); 38379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 38399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* newmem = internal_malloc(m, bytes); 38409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (newmem != 0) { 38419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t oc = oldsize - overhead_for(oldp); 38429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); 38439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_free(m, oldmem); 38449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return newmem; 38469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 38499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 38509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* --------------------------- memalign support -------------------------- */ 38529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void* internal_memalign(mstate m, size_t alignment, size_t bytes) { 38549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ 38559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_malloc(m, bytes); 38569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ 38579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignment = MIN_CHUNK_SIZE; 38589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ 38599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t a = MALLOC_ALIGNMENT << 1; 38609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (a < alignment) a <<= 1; 38619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignment = a; 38629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes >= MAX_REQUEST - alignment) { 38659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (m != 0) { /* Test isn't needed but avoids compiler warning */ 38669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MALLOC_FAILURE_ACTION; 38679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 38699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 38709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nb = request2size(bytes); 38719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; 38729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* mem = (char*)internal_malloc(m, req); 38739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) { 38749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* leader = 0; 38759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* trailer = 0; 38769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(mem); 38779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (PREACTION(m)) return 0; 38799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ 38809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 38819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Find an aligned spot inside chunk. Since we need to give 38829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall back leading space in a chunk of at least MIN_CHUNK_SIZE, if 38839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the first calculation places us at a spot with less than 38849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MIN_CHUNK_SIZE leader, we can move to the next aligned spot. 38859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall We've allocated enough total room so that this is always 38869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall possible. 38879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 38889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* br = (char*)mem2chunk((size_t)(((size_t)(mem + 38899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall alignment - 38909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SIZE_T_ONE)) & 38919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall -alignment)); 38929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? 38939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall br : br+alignment; 38949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr newp = (mchunkptr)pos; 38959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t leadsize = pos - (char*)(p); 38969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t newsize = chunksize(p) - leadsize; 38979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 38989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ 38999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp->prev_foot = p->prev_foot + leadsize; 39009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall newp->head = (newsize|CINUSE_BIT); 39019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* Otherwise, give back leader, use the rest */ 39039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, newp, newsize); 39049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, p, leadsize); 39059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall leader = chunk2mem(p); 39069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = newp; 39089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Give back spare room at the end */ 39119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!is_mmapped(p)) { 39129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size = chunksize(p); 39139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (size > nb + MIN_CHUNK_SIZE) { 39149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t remainder_size = size - nb; 39159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr remainder = chunk_plus_offset(p, nb); 39169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, p, nb); 39179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse(m, remainder, remainder_size); 39189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall trailer = chunk2mem(remainder); 39199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert (chunksize(p) >= nb); 39239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert((((size_t)(chunk2mem(p))) % alignment) == 0); 39249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(m, p); 39259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 39269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (leader != 0) { 39279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_free(m, leader); 39289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (trailer != 0) { 39309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_free(m, trailer); 39319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunk2mem(p); 39339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 39369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 39379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ------------------------ comalloc/coalloc support --------------------- */ 39399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void** ialloc(mstate m, 39419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t n_elements, 39429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t* sizes, 39439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int opts, 39449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* chunks[]) { 39459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 39469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This provides common support for independent_X routines, handling 39479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall all of the combinations that can result. 39489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The opts arg has: 39509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bit 0 set if all elements are same size (using sizes[0]) 39519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bit 1 set if elements should be zeroed 39529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 39539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t element_size; /* chunksize of each element, if all same */ 39559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t contents_size; /* total size of elements */ 39569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t array_size; /* request size of pointer array */ 39579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem; /* malloced aggregate space */ 39589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p; /* corresponding chunk */ 39599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t remainder_size; /* remaining bytes while splitting */ 39609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void** marray; /* either "chunks" or malloced ptr array */ 39619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr array_chunk; /* chunk for malloced ptr array */ 39629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t was_enabled; /* to disable mmap */ 39639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size; 39649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t i; 39659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* compute array length, if needed */ 39679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (chunks != 0) { 39689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (n_elements == 0) 39699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunks; /* nothing to do */ 39709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall marray = chunks; 39719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall array_size = 0; 39729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 39749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* if empty req, must still return chunk representing empty array */ 39759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (n_elements == 0) 39769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (void**)internal_malloc(m, 0); 39779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall marray = 0; 39789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall array_size = request2size(n_elements * (sizeof(void*))); 39799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* compute total element size */ 39829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (opts & 0x1) { /* all-same-size */ 39839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall element_size = request2size(*sizes); 39849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contents_size = n_elements * element_size; 39859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* add up all the sizes */ 39879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall element_size = 0; 39889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contents_size = 0; 39899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i != n_elements; ++i) 39909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contents_size += request2size(sizes[i]); 39919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 39929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size = contents_size + array_size; 39949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 39959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 39969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Allocate the aggregate chunk. First disable direct-mmapping so 39979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall malloc won't use it, since we would not be able to later 39989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free/realloc space internal to a segregated mmap region. 39999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 40009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall was_enabled = use_mmap(m); 40019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall disable_mmap(m); 40029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = internal_malloc(m, size - CHUNK_OVERHEAD); 40039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (was_enabled) 40049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall enable_mmap(m); 40059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem == 0) 40069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 40079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (PREACTION(m)) return 0; 40099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = mem2chunk(mem); 40109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall remainder_size = chunksize(p); 40119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(!is_mmapped(p)); 40139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (opts & 0x2) { /* optionally clear the elements */ 40159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); 40169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If not provided, allocate the pointer array as final part of chunk */ 40199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (marray == 0) { 40209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t array_chunk_size; 40219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall array_chunk = chunk_plus_offset(p, contents_size); 40229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall array_chunk_size = remainder_size - contents_size; 40239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall marray = (void**) (chunk2mem(array_chunk)); 40249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); 40259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall remainder_size = contents_size; 40269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* split out elements */ 40299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; ; ++i) { 40309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall marray[i] = chunk2mem(p); 40319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (i != n_elements-1) { 40329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (element_size != 0) 40339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size = element_size; 40349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 40359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size = request2size(sizes[i]); 40369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall remainder_size -= size; 40379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, p, size); 40389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = chunk_plus_offset(p, size); 40399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* the final element absorbs any overallocation slop */ 40419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); 40429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 40439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if DEBUG 40479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (marray != chunks) { 40489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* final element must have exactly exhausted chunk */ 40499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (element_size != 0) { 40509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(remainder_size == element_size); 40519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 40539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(remainder_size == request2size(sizes[i])); 40549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(m, mem2chunk(marray)); 40569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 40579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i != n_elements; ++i) 40589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(m, mem2chunk(marray[i])); 40599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* DEBUG */ 40619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(m); 40639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return marray; 40649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 40659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------------- public routines ---------------------------- */ 40689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !ONLY_MSPACES 40709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlmalloc(size_t bytes) { 40729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 40739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Basic algorithm: 40749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall If a small request (< 256 bytes minus per-chunk overhead): 40759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1. If one exists, use a remainderless chunk in associated smallbin. 40769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (Remainderless means that there are too few excess bytes to 40779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall represent as a chunk.) 40789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2. If it is big enough, use the dv chunk, which is normally the 40799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall chunk adjacent to the one used for the most recent small request. 40809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3. If one exists, split the smallest available chunk in a bin, 40819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall saving remainder in dv. 40829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4. If it is big enough, use the top chunk. 40839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5. If available, get memory from system and use it 40849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Otherwise, for a large request: 40859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1. Find the smallest available binned chunk that fits, and use it 40869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if it is better fitting than dv chunk, splitting if necessary. 40879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2. If better fitting than any binned chunk, use the dv chunk. 40889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3. If it is big enough, use the top chunk. 40899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4. If request size >= mmap threshold, try to directly mmap this chunk. 40909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5. If available, get memory from system and use it 40919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The ugly goto's here ensure that postaction occurs along all paths. 40939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 40949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 40959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(gm)) { 40969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem; 40979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nb; 40989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes <= MAX_SMALL_REQUEST) { 40999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t idx; 41009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t smallbits; 41019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); 41029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall idx = small_index(nb); 41039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall smallbits = gm->smallmap >> idx; 41049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ 41069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr b, p; 41079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall idx += ~smallbits & 1; /* Uses next bin if idx empty */ 41089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall b = smallbin_at(gm, idx); 41099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = b->fd; 41109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(p) == small_index2size(idx)); 41119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_first_small_chunk(gm, b, p, idx); 41129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(gm, p, small_index2size(idx)); 41139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 41149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (nb > gm->dvsize) { 41199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ 41209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr b, p, r; 41219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize; 41229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 41239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); 41249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leastbit = least_bit(leftbits); 41259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_bit2idx(leastbit, i); 41269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall b = smallbin_at(gm, i); 41279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = b->fd; 41289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(p) == small_index2size(i)); 41299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_first_small_chunk(gm, b, p, i); 41309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rsize = small_index2size(i) - nb; 41319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fit here cannot be remainderless if 4byte sizes */ 41329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) 41339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(gm, p, small_index2size(i)); 41349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 41359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 41369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r = chunk_plus_offset(p, nb); 41379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 41389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall replace_dv(gm, r, rsize); 41399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 41419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { 41469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (bytes >= MAX_REQUEST) 41529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ 41539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 41549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = pad_request(bytes); 41559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { 41569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (nb <= gm->dvsize) { 41629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = gm->dvsize - nb; 41639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = gm->dv; 41649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ 41659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = gm->dv = chunk_plus_offset(p, nb); 41669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gm->dvsize = rsize; 41679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 41689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 41699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* exhaust dv */ 41719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dvs = gm->dvsize; 41729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gm->dvsize = 0; 41739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gm->dv = 0; 41749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(gm, p, dvs); 41759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 41779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (nb < gm->topsize) { /* Split top */ 41829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = gm->topsize -= nb; 41839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = gm->top; 41849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = gm->top = chunk_plus_offset(p, nb); 41859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r->head = rsize | PINUSE_BIT; 41869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(gm, p, nb); 41879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 41889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(gm, gm->top); 41899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(gm, mem, nb); 41909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 41919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = sys_alloc(gm, nb); 41949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 41959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall postaction: 41969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(gm); 41979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mem; 41989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 41999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 42009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 42019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 42029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 42039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid dlfree(void* mem) { 42049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 42059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Consolidate freed chunks with preceeding or succeeding bordering 42069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall free chunks, if they exist, and then place in a bin. Intermixed 42079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with special cases for top, dv, mmapped chunks, and usage errors. 42089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 42099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 42109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) { 42119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(mem); 42129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if FOOTERS 42139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate fm = get_mstate_for(p); 42149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(fm)) { 42159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(fm, p); 42169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 42179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 42199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define fm gm 42209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 42219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(fm)) { 42229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(fm, p); 42239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { 42249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = chunksize(p); 42259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr next = chunk_plus_offset(p, psize); 42269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!pinuse(p)) { 42279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t prevsize = p->prev_foot; 42289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((prevsize & IS_MMAPPED_BIT) != 0) { 42299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall prevsize &= ~IS_MMAPPED_BIT; 42309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += prevsize + MMAP_FOOT_PAD; 42319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) 42329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->footprint -= psize; 42339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 42369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr prev = chunk_minus_offset(p, prevsize); 42379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += prevsize; 42389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = prev; 42399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ 42409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p != fm->dv) { 42419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_chunk(fm, p, prevsize); 42429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if ((next->head & INUSE_BITS) == INUSE_BITS) { 42449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = psize; 42459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(p, psize, next); 42469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 42509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto erroraction; 42519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 42549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { 42559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(next)) { /* consolidate forward */ 42569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (next == fm->top) { 42579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = fm->topsize += psize; 42589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->top = p; 42599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p->head = tsize | PINUSE_BIT; 42609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == fm->dv) { 42619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dv = 0; 42629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = 0; 42639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (should_trim(fm, tsize)) 42659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sys_trim(fm, 0); 42669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (next == fm->dv) { 42699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dsize = fm->dvsize += psize; 42709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dv = p; 42719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(p, dsize); 42729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 42759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nsize = chunksize(next); 42769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += nsize; 42779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_chunk(fm, next, nsize); 42789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(p, psize); 42799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == fm->dv) { 42809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = psize; 42819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 42869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(p, psize, next); 42879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_chunk(fm, p, psize); 42889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_free_chunk(fm, p); 42899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 42909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall erroraction: 42939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(fm, p); 42949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall postaction: 42959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(fm); 42969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 42989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !FOOTERS 42999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#undef fm 43009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 43019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlcalloc(size_t n_elements, size_t elem_size) { 43049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem; 43059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t req = 0; 43069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (n_elements != 0) { 43079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall req = n_elements * elem_size; 43089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (((n_elements | elem_size) & ~(size_t)0xffff) && 43099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (req / n_elements != elem_size)) 43109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall req = MAX_SIZE_T; /* force downstream failure on overflow */ 43119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 43129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = dlmalloc(req); 43139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0 && calloc_must_clear(mem2chunk(mem))) 43149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset(mem, 0, req); 43159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mem; 43169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlrealloc(void* oldmem, size_t bytes) { 43199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (oldmem == 0) 43209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return dlmalloc(bytes); 43219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef REALLOC_ZERO_BYTES_FREES 43229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes == 0) { 43239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dlfree(oldmem); 43249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 43259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 43269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* REALLOC_ZERO_BYTES_FREES */ 43279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 43289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ! FOOTERS 43299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate m = gm; 43309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 43319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate m = get_mstate_for(mem2chunk(oldmem)); 43329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(m)) { 43339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(m, oldmem); 43349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 43359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 43369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 43379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_realloc(m, oldmem, bytes); 43389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 43399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlmemalign(size_t alignment, size_t bytes) { 43429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_memalign(gm, alignment, bytes); 43439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** dlindependent_calloc(size_t n_elements, size_t elem_size, 43469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* chunks[]) { 43479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = elem_size; /* serves as 1-element array */ 43489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ialloc(gm, n_elements, &sz, 3, chunks); 43499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** dlindependent_comalloc(size_t n_elements, size_t sizes[], 43529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* chunks[]) { 43539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ialloc(gm, n_elements, sizes, 0, chunks); 43549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlvalloc(size_t bytes) { 43579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t pagesz; 43589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); 43599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pagesz = mparams.page_size; 43609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return dlmemalign(pagesz, bytes); 43619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* dlpvalloc(size_t bytes) { 43649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t pagesz; 43659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); 43669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pagesz = mparams.page_size; 43679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); 43689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint dlmalloc_trim(size_t pad) { 43719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int result = 0; 43729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(gm)) { 43739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall result = sys_trim(gm, pad); 43749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(gm); 43759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 43769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return result; 43779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_footprint(void) { 43809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return gm->footprint; 43819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_max_footprint(void) { 43849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return gm->max_footprint; 43859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 43889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct mallinfo dlmallinfo(void) { 43899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_mallinfo(gm); 43909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 43929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid dlmalloc_stats() { 43949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_malloc_stats(gm); 43959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 43969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 43979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t dlmalloc_usable_size(void* mem) { 43989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) { 43999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(mem); 44009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cinuse(p)) 44019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return chunksize(p) - overhead_for(p); 44029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 44049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint dlmallopt(int param_number, int value) { 44079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return change_mparam(param_number, value); 44089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !ONLY_MSPACES */ 44119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------------- user mspaces ---------------------------- */ 44139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if MSPACES 44159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic mstate init_user_mstate(char* tbase, size_t tsize) { 44179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t msize = pad_request(sizeof(struct malloc_state)); 44189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr mn; 44199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr msp = align_as_chunk(tbase); 44209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate m = (mstate)(chunk2mem(msp)); 44219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset(m, 0, msize); 44229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall INITIAL_LOCK(&m->mutex); 44239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msp->head = (msize|PINUSE_BIT|CINUSE_BIT); 44249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.base = m->least_addr = tbase; 44259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.size = m->footprint = m->max_footprint = tsize; 44269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->magic = mparams.magic; 44279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->mflags = mparams.default_mflags; 44289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall disable_contiguous(m); 44299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_bins(m); 44309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mn = next_chunk(mem2chunk(m)); 44319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); 44329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(m, m->top); 44339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return m; 44349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallmspace create_mspace(size_t capacity, int locked) { 44379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate m = 0; 44389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t msize = pad_request(sizeof(struct malloc_state)); 44399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); /* Ensure pagesize etc initialized */ 44409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { 44429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rs = ((capacity == 0)? mparams.granularity : 44439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (capacity + TOP_FOOT_SIZE + msize)); 44449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = granularity_align(rs); 44459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* tbase = (char*)(CALL_MMAP(tsize)); 44469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tbase != CMFAIL) { 44479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = init_user_mstate(tbase, tsize); 44489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.sflags = IS_MMAPPED_BIT; 44499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_lock(m, locked); 44509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (mspace)m; 44539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallmspace create_mspace_with_base(void* base, size_t capacity, int locked) { 44569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate m = 0; 44579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t msize = pad_request(sizeof(struct malloc_state)); 44589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall init_mparams(); /* Ensure pagesize etc initialized */ 44599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (capacity > msize + TOP_FOOT_SIZE && 44619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { 44629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m = init_user_mstate((char*)base, capacity); 44639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall m->seg.sflags = EXTERN_BIT; 44649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_lock(m, locked); 44659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (mspace)m; 44679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t destroy_mspace(mspace msp) { 44709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t freed = 0; 44719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 44729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ok_magic(ms)) { 44739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall msegmentptr sp = &ms->seg; 44749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (sp != 0) { 44759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char* base = sp->base; 44769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t size = sp->size; 44779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flag_t flag = sp->sflags; 44789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sp = sp->next; 44799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && 44809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CALL_MUNMAP(base, size) == 0) 44819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall freed += size; 44829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 44859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 44869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 44879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return freed; 44889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 44899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 44919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace versions of routines are near-clones of the global 44929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall versions. This is not so nice but better than the alternatives. 44939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 44949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 44969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_malloc(mspace msp, size_t bytes) { 44979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 44989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 44999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 45009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 45019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(ms)) { 45039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem; 45049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nb; 45059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes <= MAX_SMALL_REQUEST) { 45069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t idx; 45079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t smallbits; 45089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); 45099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall idx = small_index(nb); 45109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall smallbits = ms->smallmap >> idx; 45119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 45129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ 45139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr b, p; 45149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall idx += ~smallbits & 1; /* Uses next bin if idx empty */ 45159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall b = smallbin_at(ms, idx); 45169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = b->fd; 45179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(p) == small_index2size(idx)); 45189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_first_small_chunk(ms, b, p, idx); 45199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(ms, p, small_index2size(idx)); 45209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 45219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 45259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (nb > ms->dvsize) { 45269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ 45279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr b, p, r; 45289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize; 45299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bindex_t i; 45309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); 45319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall binmap_t leastbit = least_bit(leftbits); 45329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall compute_bit2idx(leastbit, i); 45339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall b = smallbin_at(ms, i); 45349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = b->fd; 45359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall assert(chunksize(p) == small_index2size(i)); 45369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_first_small_chunk(ms, b, p, i); 45379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rsize = small_index2size(i) - nb; 45389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fit here cannot be remainderless if 4byte sizes */ 45399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) 45409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(ms, p, small_index2size(i)); 45419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 45429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 45439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r = chunk_plus_offset(p, nb); 45449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 45459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall replace_dv(ms, r, rsize); 45469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 45489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 45529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { 45539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (bytes >= MAX_REQUEST) 45599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ 45609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 45619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nb = pad_request(bytes); 45629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { 45639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 45689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (nb <= ms->dvsize) { 45699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = ms->dvsize - nb; 45709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = ms->dv; 45719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ 45729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = ms->dv = chunk_plus_offset(p, nb); 45739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ms->dvsize = rsize; 45749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(r, rsize); 45759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 45769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { /* exhaust dv */ 45789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dvs = ms->dvsize; 45799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ms->dvsize = 0; 45809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ms->dv = 0; 45819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_inuse_and_pinuse(ms, p, dvs); 45829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 45849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 45889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (nb < ms->topsize) { /* Split top */ 45899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t rsize = ms->topsize -= nb; 45909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = ms->top; 45919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr r = ms->top = chunk_plus_offset(p, nb); 45929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r->head = rsize | PINUSE_BIT; 45939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_inuse_chunk(ms, p, nb); 45949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = chunk2mem(p); 45959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_top_chunk(ms, ms->top); 45969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_malloced_chunk(ms, mem, nb); 45979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 45989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 45999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 46009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = sys_alloc(ms, nb); 46019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 46029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall postaction: 46039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(ms); 46049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mem; 46059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 46079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 46089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 46099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 46109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid mspace_free(mspace msp, void* mem) { 46119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0) { 46129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(mem); 46139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if FOOTERS 46149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate fm = get_mstate_for(p); 46159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 46169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate fm = (mstate)msp; 46179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 46189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(fm)) { 46199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(fm, p); 46209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 46219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(fm)) { 46239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_inuse_chunk(fm, p); 46249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { 46259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t psize = chunksize(p); 46269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr next = chunk_plus_offset(p, psize); 46279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!pinuse(p)) { 46289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t prevsize = p->prev_foot; 46299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((prevsize & IS_MMAPPED_BIT) != 0) { 46309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall prevsize &= ~IS_MMAPPED_BIT; 46319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += prevsize + MMAP_FOOT_PAD; 46329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) 46339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->footprint -= psize; 46349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 46379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr prev = chunk_minus_offset(p, prevsize); 46389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += prevsize; 46399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p = prev; 46409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ 46419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p != fm->dv) { 46429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_chunk(fm, p, prevsize); 46439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if ((next->head & INUSE_BITS) == INUSE_BITS) { 46459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = psize; 46469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(p, psize, next); 46479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 46519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto erroraction; 46529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 46559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { 46569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!cinuse(next)) { /* consolidate forward */ 46579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (next == fm->top) { 46589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t tsize = fm->topsize += psize; 46599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->top = p; 46609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p->head = tsize | PINUSE_BIT; 46619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == fm->dv) { 46629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dv = 0; 46639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = 0; 46649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (should_trim(fm, tsize)) 46669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sys_trim(fm, 0); 46679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (next == fm->dv) { 46709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t dsize = fm->dvsize += psize; 46719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dv = p; 46729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(p, dsize); 46739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 46769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t nsize = chunksize(next); 46779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall psize += nsize; 46789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unlink_chunk(fm, next, nsize); 46799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_size_and_pinuse_of_free_chunk(p, psize); 46809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (p == fm->dv) { 46819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fm->dvsize = psize; 46829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 46879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall set_free_with_pinuse(p, psize, next); 46889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall insert_chunk(fm, p, psize); 46899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall check_free_chunk(fm, p); 46909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto postaction; 46919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall erroraction: 46949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(fm, p); 46959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall postaction: 46969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(fm); 46979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 46999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { 47029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void* mem; 47039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t req = 0; 47049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 47069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (n_elements != 0) { 47109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall req = n_elements * elem_size; 47119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (((n_elements | elem_size) & ~(size_t)0xffff) && 47129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (req / n_elements != elem_size)) 47139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall req = MAX_SIZE_T; /* force downstream failure on overflow */ 47149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mem = internal_malloc(ms, req); 47169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mem != 0 && calloc_must_clear(mem2chunk(mem))) 47179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset(mem, 0, req); 47189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mem; 47199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { 47229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (oldmem == 0) 47239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return mspace_malloc(msp, bytes); 47249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef REALLOC_ZERO_BYTES_FREES 47259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bytes == 0) { 47269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mspace_free(msp, oldmem); 47279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* REALLOC_ZERO_BYTES_FREES */ 47309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 47319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if FOOTERS 47329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mchunkptr p = mem2chunk(oldmem); 47339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = get_mstate_for(p); 47349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else /* FOOTERS */ 47359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* FOOTERS */ 47379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 47389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_realloc(ms, oldmem, bytes); 47429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { 47469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 47489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_memalign(ms, alignment, bytes); 47529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** mspace_independent_calloc(mspace msp, size_t n_elements, 47559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t elem_size, void* chunks[]) { 47569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sz = elem_size; /* serves as 1-element array */ 47579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 47599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ialloc(ms, n_elements, &sz, 3, chunks); 47639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid** mspace_independent_comalloc(mspace msp, size_t n_elements, 47669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t sizes[], void* chunks[]) { 47679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 47699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 47719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ialloc(ms, n_elements, sizes, 0, chunks); 47739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint mspace_trim(mspace msp, size_t pad) { 47769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int result = 0; 47779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ok_magic(ms)) { 47799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!PREACTION(ms)) { 47809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall result = sys_trim(ms, pad); 47819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall POSTACTION(ms); 47829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 47859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return result; 47889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 47909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid mspace_malloc_stats(mspace msp) { 47919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 47929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ok_magic(ms)) { 47939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall internal_malloc_stats(ms); 47949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 47969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 47979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 47989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 47999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t mspace_footprint(mspace msp) { 48019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t result; 48029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 48039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ok_magic(ms)) { 48049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall result = ms->footprint; 48059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 48069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 48079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return result; 48089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 48099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallsize_t mspace_max_footprint(mspace msp) { 48129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size_t result; 48139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 48149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ok_magic(ms)) { 48159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall result = ms->max_footprint; 48169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 48179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 48189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return result; 48199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 48209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if !NO_MALLINFO 48239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct mallinfo mspace_mallinfo(mspace msp) { 48249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mstate ms = (mstate)msp; 48259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!ok_magic(ms)) { 48269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall USAGE_ERROR_ACTION(ms,ms); 48279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 48289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return internal_mallinfo(ms); 48299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 48309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* NO_MALLINFO */ 48319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint mspace_mallopt(int param_number, int value) { 48339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return change_mparam(param_number, value); 48349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 48359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* MSPACES */ 48379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* -------------------- Alternative MORECORE functions ------------------- */ 48399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 48419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Guidelines for creating a custom version of MORECORE: 48429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * For best performance, MORECORE should allocate in multiples of pagesize. 48449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * MORECORE may allocate more memory than requested. (Or even less, 48459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but this will usually result in a malloc failure.) 48469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * MORECORE must not allocate memory when given argument zero, but 48479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall instead return one past the end address of memory from previous 48489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nonzero call. 48499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * For best performance, consecutive calls to MORECORE with positive 48509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall arguments should return increasing addresses, indicating that 48519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall space has been contiguously extended. 48529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Even though consecutive calls to MORECORE need not return contiguous 48539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall addresses, it must be OK for malloc'ed chunks to span multiple 48549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall regions in those cases where they do happen to be contiguous. 48559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * MORECORE need not handle negative arguments -- it may instead 48569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall just return MFAIL when given negative arguments. 48579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Negative arguments are always multiples of pagesize. MORECORE 48589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall must not misinterpret negative args as large positive unsigned 48599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall args. You can suppress all such calls from even occurring by defining 48609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MORECORE_CANNOT_TRIM, 48619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall As an example alternative MORECORE, here is a custom allocator 48639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kindly contributed for pre-OSX macOS. It uses virtually but not 48649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall necessarily physically contiguous non-paged memory (locked in, 48659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall present and won't get swapped out). You can use it by uncommenting 48669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this section, adding some #includes, and setting up the appropriate 48679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall defines above: 48689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #define MORECORE osMoreCore 48709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall There is also a shutdown routine that should somehow be called for 48729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cleanup upon program exit. 48739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #define MAX_POOL_ENTRIES 100 48759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #define MINIMUM_MORECORE_SIZE (64 * 1024U) 48769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static int next_os_pool; 48779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void *our_os_pools[MAX_POOL_ENTRIES]; 48789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void *osMoreCore(int size) 48809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 48819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void *ptr = 0; 48829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static void *sbrk_top = 0; 48839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 48849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (size > 0) 48859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 48869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (size < MINIMUM_MORECORE_SIZE) 48879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall size = MINIMUM_MORECORE_SIZE; 48889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CurrentExecutionLevel() == kTaskLevel) 48899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); 48909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ptr == 0) 48919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 48929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (void *) MFAIL; 48939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 48949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // save ptrs so they can be freed during cleanup 48959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall our_os_pools[next_os_pool] = ptr; 48969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall next_os_pool++; 48979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); 48989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sbrk_top = (char *) ptr + size; 48999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ptr; 49009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if (size < 0) 49029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 49039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // we don't currently support shrink behavior 49049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (void *) MFAIL; 49059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 49079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 49089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return sbrk_top; 49099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // cleanup any allocated memory pools 49139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // called as last thing before shutting down driver 49149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void osCleanupMem(void) 49169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 49179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall void **ptr; 49189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) 49209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (*ptr) 49219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 49229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PoolDeallocate(*ptr); 49239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *ptr = 0; 49249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 49269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 49289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* ----------------------------------------------------------------------- 49319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallHistory: 49329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) 49339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add max_footprint functions 49349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Ensure all appropriate literals are size_t 49359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix conditional compilation problem for some #define settings 49369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Avoid concatenating segments with the one provided 49379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in create_mspace_with_base 49389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Rename some variables to avoid compiler shadowing warnings 49399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use explicit lock initialization. 49409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Better handling of sbrk interference. 49419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Simplify and fix segment insertion, trimming and mspace_destroy 49429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x 49439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Thanks especially to Dennis Flanagan for help on these. 49449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) 49469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix memalign brace error. 49479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) 49499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix improper #endif nesting in C++ 49509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add explicit casts needed for C++ 49519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) 49539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use trees for large bins 49549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Support mspaces 49559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use segments to unify sbrk-based and mmap-based system allocation, 49569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall removing need for emulation on most platforms without sbrk. 49579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Default safety checks 49589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Optional footer checks. Thanks to William Robertson for the idea. 49599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Internal code refactoring 49609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Incorporate suggestions and platform-specific changes. 49619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, 49629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Aaron Bachmann, Emery Berger, and others. 49639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Speed up non-fastbin processing enough to remove fastbins. 49649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Remove useless cfree() to avoid conflicts with other apps. 49659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Remove internal memcpy, memset. Compilers handle builtins better. 49669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Remove some options that no one ever used and rename others. 49679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) 49699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix malloc_state bitmap array misdeclaration 49709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) 49729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Allow tuning of FIRST_SORTED_BIN_SIZE 49739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. 49749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Better detection and support for non-contiguousness of MORECORE. 49759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger 49769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Bypass most of malloc if no frees. Thanks To Emery Berger. 49779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix freeing of old top non-contiguous chunk im sysmalloc. 49789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Raised default trim and map thresholds to 256K. 49799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix mmap-related #defines. Thanks to Lubos Lunak. 49809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. 49819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Branch-free bin calculation 49829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Default trim and mmap thresholds now 256K. 49839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) 49859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Introduce independent_comalloc and independent_calloc. 49869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thanks to Michael Pachos for motivation and help. 49879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Make optional .h file available 49889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Allow > 2GB requests on 32bit systems. 49899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>. 49909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thanks also to Andreas Mueller <a.mueller at paradatec.de>, 49919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and Anonymous. 49929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for 49939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall helping test this.) 49949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * memalign: check alignment arg 49959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * realloc: don't try to shift chunks backwards, since this 49969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall leads to more fragmentation in some programs and doesn't 49979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall seem to help in any others. 49989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Collect all cases in malloc requiring system memory into sysmalloc 49999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use mmap as backup to sbrk 50009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Place all internal state in malloc_state 50019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Introduce fastbins (although similar to 2.5.1) 50029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Many minor tunings and cosmetic improvements 50039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK 50049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS 50059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Thanks to Tony E. Bennett <tbennett@nvidia.com> and others. 50069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Include errno.h to support default failure action. 50079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) 50099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * return null for negative arguments 50109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com> 50119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' 50129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (e.g. WIN32 platforms) 50139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Cleanup header file inclusion for WIN32 platforms 50149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Cleanup code to avoid Microsoft Visual C++ compiler complaints 50159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing 50169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memory allocation routines 50179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) 50189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to 50199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall usage of 'assert' in non-WIN32 code 50209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to 50219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall avoid infinite loop 50229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Always call 'fREe()' rather than 'free()' 50239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) 50259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fixed ordering problem with boundary-stamping 50269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) 50289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added pvalloc, as recommended by H.J. Liu 50299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added 64bit pointer support mainly from Wolfram Gloger 50309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added anonymously donated WIN32 sbrk emulation 50319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen 50329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * malloc_extend_top: fix mask error that caused wastage after 50339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall foreign sbrks 50349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add linux mremap support code from HJ Liu 50359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) 50379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Integrated most documentation with the code. 50389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add support for mmap, with help from 50399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Wolfram Gloger (Gloger@lrz.uni-muenchen.de). 50409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use last_remainder in more cases. 50419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Pack bins using idea from colin@nyx10.cs.du.edu 50429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use ordered bins instead of best-fit threshhold 50439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Eliminate block-local decls to simplify tracing and debugging. 50449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Support another case of realloc via move into top 50459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Fix error occuring when initial sbrk_base not word-aligned. 50469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Rely on page size for units instead of SBRK_UNIT to 50479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall avoid surprises about sbrk alignment conventions. 50489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add mallinfo, mallopt. Thanks to Raymond Nijssen 50499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (raymond@es.ele.tue.nl) for the suggestion. 50509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add `pad' argument to malloc_trim and top_pad mallopt parameter. 50519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * More precautions for cases where other routines call sbrk, 50529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). 50539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added macros etc., allowing use in linux libc from 50549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall H.J. Lu (hjl@gnu.ai.mit.edu) 50559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Inverted this history list 50569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) 50589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Re-tuned and fixed to behave more nicely with V2.6.0 changes. 50599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Removed all preallocation code since under current scheme 50609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the work required to undo bad preallocations exceeds 50619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall the work saved in good cases for most test programs. 50629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * No longer use return list or unconsolidated bins since 50639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall no scheme using them consistently outperforms those that don't 50649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall given above changes. 50659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use best fit for very large chunks to prevent some worst-cases. 50669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added some support for debugging 50679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) 50699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Removed footers when chunks are in use. Thanks to 50709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Paul Wilson (wilson@cs.texas.edu) for the suggestion. 50719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) 50739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Added malloc_trim, with help from Wolfram Gloger 50749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (wmglo@Dent.MED.Uni-Muenchen.DE). 50759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) 50779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) 50799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * realloc: try to expand in both directions 50809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * malloc: swap order of clean-bin strategy; 50819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * realloc: only conditionally expand backwards 50829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Try not to scavenge used bins 50839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use bin counts as a guide to preallocation 50849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Occasionally bin return list chunks in first scan 50859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add a few optimizations from colin@nyx10.cs.du.edu 50869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) 50889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * faster bin computation & slightly different binning 50899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * merged all consolidations to one part of malloc proper 50909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (eliminating old malloc_find_space & malloc_clean_bin) 50919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Scan 2 returns chunks (not just 1) 50929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Propagate failure in realloc if malloc returns 0 50939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Add stuff to allow compilation on non-ANSI compilers 50949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall from kpv@research.att.com 50959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 50969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) 50979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * removed potential for odd address access in prev_chunk 50989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * removed dependency on getpagesize.h 50999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * misc cosmetics and a bit more internal documentation 51009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * anticosmetics: mangled names in macros to evade debugger strangeness 51019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * tested on sparc, hp-700, dec-mips, rs6000 51029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with gcc & native cc (hp, dec only) allowing 51039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Detlefs & Zorn comparison study (in SIGPLAN Notices.) 51049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 51059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) 51069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Based loosely on libg++-1.2X malloc. (It retains some of the overall 51079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall structure of old version, but most details differ.) 51089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 51099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 51109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 51119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* !HAVE_MALLOC */ 5112