Go to the documentation of this file.
22 #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
23 #define SDL_DISABLE_ANALYZE_MACROS 1
26 #include "../SDL_internal.h"
34 #define LACKS_SYS_TYPES_H
36 #define LACKS_STRINGS_H
37 #define LACKS_STRING_H
38 #define LACKS_STDLIB_H
489 #define WIN32_LEAN_AND_MEAN
492 #define HAVE_MORECORE 0
493 #define LACKS_UNISTD_H
494 #define LACKS_SYS_PARAM_H
495 #define LACKS_SYS_MMAN_H
496 #define LACKS_STRING_H
497 #define LACKS_STRINGS_H
498 #define LACKS_SYS_TYPES_H
499 #define LACKS_ERRNO_H
500 #define LACKS_FCNTL_H
501 #define MALLOC_FAILURE_ACTION
502 #define MMAP_CLEARS 0
509 #define HAVE_MORECORE 0
510 #define LACKS_SYS_MMAN_H
513 #if defined(DARWIN) || defined(_DARWIN)
515 #ifndef HAVE_MORECORE
516 #define HAVE_MORECORE 0
521 #ifndef LACKS_SYS_TYPES_H
522 #include <sys/types.h>
526 #define MAX_SIZE_T (~(size_t)0)
529 #define ONLY_MSPACES 0
538 #ifndef MALLOC_ALIGNMENT
539 #define MALLOC_ALIGNMENT ((size_t)8U)
545 #define ABORT abort()
547 #ifndef ABORT_ON_ASSERT_FAILURE
548 #define ABORT_ON_ASSERT_FAILURE 1
550 #ifndef PROCEED_ON_ERROR
551 #define PROCEED_ON_ERROR 0
563 #define MMAP_CLEARS 1
567 #define HAVE_MREMAP 1
569 #define HAVE_MREMAP 0
572 #ifndef MALLOC_FAILURE_ACTION
573 #define MALLOC_FAILURE_ACTION errno = ENOMEM;
575 #ifndef HAVE_MORECORE
577 #define HAVE_MORECORE 0
579 #define HAVE_MORECORE 1
583 #define MORECORE_CONTIGUOUS 0
586 #define MORECORE sbrk
588 #ifndef MORECORE_CONTIGUOUS
589 #define MORECORE_CONTIGUOUS 1
592 #ifndef DEFAULT_GRANULARITY
593 #if MORECORE_CONTIGUOUS
594 #define DEFAULT_GRANULARITY (0)
596 #define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
599 #ifndef DEFAULT_TRIM_THRESHOLD
600 #ifndef MORECORE_CANNOT_TRIM
601 #define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
603 #define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
606 #ifndef DEFAULT_MMAP_THRESHOLD
608 #define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
610 #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
613 #ifndef USE_BUILTIN_FFS
614 #define USE_BUILTIN_FFS 0
616 #ifndef USE_DEV_RANDOM
617 #define USE_DEV_RANDOM 0
620 #define NO_MALLINFO 0
622 #ifndef MALLINFO_FIELD_TYPE
623 #define MALLINFO_FIELD_TYPE size_t
627 #define memset SDL_memset
630 #define memcpy SDL_memcpy
640 #define M_TRIM_THRESHOLD (-1)
641 #define M_GRANULARITY (-2)
642 #define M_MMAP_THRESHOLD (-3)
671 #ifdef HAVE_USR_INCLUDE_MALLOC_H
672 #include "/usr/include/malloc.h"
701 #ifndef USE_DL_PREFIX
702 #define dlcalloc calloc
704 #define dlmalloc malloc
705 #define dlmemalign memalign
706 #define dlrealloc realloc
707 #define dlvalloc valloc
708 #define dlpvalloc pvalloc
709 #define dlmallinfo mallinfo
710 #define dlmallopt mallopt
711 #define dlmalloc_trim malloc_trim
712 #define dlmalloc_stats malloc_stats
713 #define dlmalloc_usable_size malloc_usable_size
714 #define dlmalloc_footprint malloc_footprint
715 #define dlmalloc_max_footprint malloc_max_footprint
716 #define dlindependent_calloc independent_calloc
717 #define dlindependent_comalloc independent_comalloc
1060 typedef void *mspace;
1073 mspace create_mspace(
size_t capacity,
int locked);
1081 size_t destroy_mspace(mspace msp);
1092 mspace create_mspace_with_base(
void *
base,
size_t capacity,
int locked);
1098 void *mspace_malloc(mspace msp,
size_t bytes);
1108 void mspace_free(mspace msp,
void *mem);
1119 void *mspace_realloc(mspace msp,
void *mem,
size_t newsize);
1125 void *mspace_calloc(mspace msp,
size_t n_elements,
size_t elem_size);
1131 void *mspace_memalign(mspace msp,
size_t alignment,
size_t bytes);
1137 void **mspace_independent_calloc(mspace msp,
size_t n_elements,
1144 void **mspace_independent_comalloc(mspace msp,
size_t n_elements,
1145 size_t sizes[],
void *chunks[]);
1151 size_t mspace_footprint(mspace msp);
1157 size_t mspace_max_footprint(mspace msp);
1165 struct mallinfo mspace_mallinfo(mspace msp);
1172 void mspace_malloc_stats(mspace msp);
1178 int mspace_trim(mspace msp,
size_t pad);
1183 int mspace_mallopt(
int,
int);
1204 #pragma warning( disable : 4146 )
1207 #ifndef LACKS_STDIO_H
1211 #ifndef LACKS_ERRNO_H
1217 #ifndef LACKS_STDLIB_H
1221 #if ABORT_ON_ASSERT_FAILURE
1222 #define assert(x) if(!(x)) ABORT
1229 #ifndef LACKS_STRING_H
1233 #ifndef LACKS_STRINGS_H
1234 #include <strings.h>
1238 #ifndef LACKS_SYS_MMAN_H
1239 #include <sys/mman.h>
1241 #ifndef LACKS_FCNTL_H
1246 #ifndef LACKS_UNISTD_H
1249 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
1250 extern void *sbrk(ptrdiff_t);
1256 #ifndef malloc_getpagesize
1257 # ifdef _SC_PAGESIZE
1258 # ifndef _SC_PAGE_SIZE
1259 # define _SC_PAGE_SIZE _SC_PAGESIZE
1262 # ifdef _SC_PAGE_SIZE
1263 # define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
1265 # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
1266 extern size_t getpagesize();
1267 # define malloc_getpagesize getpagesize()
1270 # define malloc_getpagesize getpagesize()
1272 # ifndef LACKS_SYS_PARAM_H
1273 # include <sys/param.h>
1275 # ifdef EXEC_PAGESIZE
1276 # define malloc_getpagesize EXEC_PAGESIZE
1280 # define malloc_getpagesize NBPG
1282 # define malloc_getpagesize (NBPG * CLSIZE)
1286 # define malloc_getpagesize NBPC
1289 # define malloc_getpagesize PAGESIZE
1291 # define malloc_getpagesize ((size_t)4096U)
1305 #define SIZE_T_SIZE (sizeof(size_t))
1306 #define SIZE_T_BITSIZE (sizeof(size_t) << 3)
1310 #define SIZE_T_ZERO ((size_t)0)
1311 #define SIZE_T_ONE ((size_t)1)
1312 #define SIZE_T_TWO ((size_t)2)
1313 #define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1)
1314 #define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2)
1315 #define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
1316 #define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U)
1319 #define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
1322 #define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
1325 #define align_offset(A)\
1326 ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
1327 ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
1339 #define MFAIL ((void*)(MAX_SIZE_T))
1340 #define CMFAIL ((char*)(MFAIL))
1343 #define IS_MMAPPED_BIT (SIZE_T_ZERO)
1344 #define USE_MMAP_BIT (SIZE_T_ZERO)
1345 #define CALL_MMAP(s) MFAIL
1346 #define CALL_MUNMAP(a, s) (-1)
1347 #define DIRECT_MMAP(s) MFAIL
1350 #define IS_MMAPPED_BIT (SIZE_T_ONE)
1351 #define USE_MMAP_BIT (SIZE_T_ONE)
1353 #if !defined(WIN32) && !defined (__OS2__)
1354 #define CALL_MUNMAP(a, s) munmap((a), (s))
1355 #define MMAP_PROT (PROT_READ|PROT_WRITE)
1356 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
1357 #define MAP_ANONYMOUS MAP_ANON
1359 #ifdef MAP_ANONYMOUS
1360 #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
1361 #define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
1367 #define MMAP_FLAGS (MAP_PRIVATE)
1368 static int dev_zero_fd = -1;
1369 #define CALL_MMAP(s) ((dev_zero_fd < 0) ? \
1370 (dev_zero_fd = open("/dev/zero", O_RDWR), \
1371 mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
1372 mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
1375 #define DIRECT_MMAP(s) CALL_MMAP(s)
1377 #elif defined(__OS2__)
1380 static void* os2mmap(
size_t size) {
1382 if (DosAllocMem(&
ptr,
size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&
1383 DosAllocMem(&
ptr,
size, PAG_COMMIT|PAG_READ|PAG_WRITE))
1388 #define os2direct_mmap(n) os2mmap(n)
1391 static int os2munmap(
void*
ptr,
size_t size) {
1393 ULONG ulSize =
size;
1395 if (DosQueryMem(
ptr, &ulSize, &ulFlags) != 0)
1397 if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||
1400 if (DosFreeMem(
ptr) != 0)
1402 ptr = (
void * ) ( (
char * )
ptr + ulSize );
1408 #define CALL_MMAP(s) os2mmap(s)
1409 #define CALL_MUNMAP(a, s) os2munmap((a), (s))
1410 #define DIRECT_MMAP(s) os2direct_mmap(s)
1419 VirtualAlloc(0,
size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
1427 void *
ptr = VirtualAlloc(0,
size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
1436 MEMORY_BASIC_INFORMATION minfo;
1439 if (VirtualQuery(cptr, &minfo,
sizeof(minfo)) == 0)
1441 if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
1442 minfo.State != MEM_COMMIT || minfo.RegionSize >
size)
1444 if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
1446 cptr += minfo.RegionSize;
1447 size -= minfo.RegionSize;
1452 #define CALL_MMAP(s) win32mmap(s)
1453 #define CALL_MUNMAP(a, s) win32munmap((a), (s))
1454 #define DIRECT_MMAP(s) win32direct_mmap(s)
1458 #if HAVE_MMAP && HAVE_MREMAP
1459 #define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
1461 #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL
1465 #define CALL_MORECORE(S) MORECORE(S)
1467 #define CALL_MORECORE(S) MFAIL
1471 #define USE_NONCONTIGUOUS_BIT (4U)
1474 #define EXTERN_BIT (8U)
1495 #if !defined(WIN32) && !defined(__OS2__)
1497 #include <pthread.h>
1498 #define MLOCK_T pthread_mutex_t
1499 #define INITIAL_LOCK(l) pthread_mutex_init(l, NULL)
1500 #define ACQUIRE_LOCK(l) pthread_mutex_lock(l)
1501 #define RELEASE_LOCK(l) pthread_mutex_unlock(l)
1504 static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;
1509 #elif defined(__OS2__)
1510 #define MLOCK_T HMTX
1511 #define INITIAL_LOCK(l) DosCreateMutexSem(0, l, 0, FALSE)
1512 #define ACQUIRE_LOCK(l) DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)
1513 #define RELEASE_LOCK(l) DosReleaseMutexSem(*l)
1515 static MLOCK_T morecore_mutex;
1525 #define MLOCK_T long
1530 #ifdef InterlockedCompareExchangePointer
1531 if (!InterlockedCompareExchange(sl, 1, 0))
1534 if (!InterlockedCompareExchange((
void **) sl, (
void *) 1, (
void *) 0))
1544 InterlockedExchange(sl, 0);
1547 #define INITIAL_LOCK(l) *(l)=0
1548 #define ACQUIRE_LOCK(l) win32_acquire_lock(l)
1549 #define RELEASE_LOCK(l) win32_release_lock(l)
1551 static MLOCK_T morecore_mutex;
1556 #define USE_LOCK_BIT (2U)
1558 #define USE_LOCK_BIT (0U)
1559 #define INITIAL_LOCK(l)
1562 #if USE_LOCKS && HAVE_MORECORE
1563 #define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex);
1564 #define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex);
1566 #define ACQUIRE_MORECORE_LOCK()
1567 #define RELEASE_MORECORE_LOCK()
1571 #define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex);
1572 #define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex);
1574 #define ACQUIRE_MAGIC_INIT_LOCK()
1575 #define RELEASE_MAGIC_INIT_LOCK()
1733 #define MCHUNK_SIZE (sizeof(mchunk))
1736 #define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
1738 #define CHUNK_OVERHEAD (SIZE_T_SIZE)
1742 #define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
1744 #define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES)
1747 #define MIN_CHUNK_SIZE\
1748 ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
1751 #define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES))
1752 #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
1754 #define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A)))
1757 #define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2)
1758 #define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
1761 #define pad_request(req) \
1762 (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
1765 #define request2size(req) \
1766 (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
1779 #define PINUSE_BIT (SIZE_T_ONE)
1780 #define CINUSE_BIT (SIZE_T_TWO)
1781 #define INUSE_BITS (PINUSE_BIT|CINUSE_BIT)
1784 #define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE)
1787 #define cinuse(p) ((p)->head & CINUSE_BIT)
1788 #define pinuse(p) ((p)->head & PINUSE_BIT)
1789 #define chunksize(p) ((p)->head & ~(INUSE_BITS))
1791 #define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT)
1792 #define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT)
1795 #define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
1796 #define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
1799 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS)))
1800 #define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
1803 #define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT)
1806 #define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot)
1807 #define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
1810 #define set_size_and_pinuse_of_free_chunk(p, s)\
1811 ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
1814 #define set_free_with_pinuse(p, s, n)\
1815 (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
1817 #define is_mmapped(p)\
1818 (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))
1821 #define overhead_for(p)\
1822 (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
1826 #define calloc_must_clear(p) (!is_mmapped(p))
1828 #define calloc_must_clear(p) (1)
1940 #define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
2007 #define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT)
2008 #define is_extern_segment(S) ((S)->sflags & EXTERN_BIT)
2089 #define NSMALLBINS (32U)
2090 #define NTREEBINS (32U)
2091 #define SMALLBIN_SHIFT (3U)
2092 #define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT)
2093 #define TREEBIN_SHIFT (8U)
2094 #define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT)
2095 #define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE)
2096 #define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
2145 #define is_global(M) ((M) == &_gm_)
2146 #define is_initialized(M) ((M)->top != 0)
2152 #define use_lock(M) ((M)->mflags & USE_LOCK_BIT)
2153 #define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT)
2154 #define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT)
2156 #define use_mmap(M) ((M)->mflags & USE_MMAP_BIT)
2157 #define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT)
2158 #define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT)
2160 #define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT)
2161 #define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT)
2163 #define set_lock(M,L)\
2164 ((M)->mflags = (L)?\
2165 ((M)->mflags | USE_LOCK_BIT) :\
2166 ((M)->mflags & ~USE_LOCK_BIT))
2169 #define page_align(S)\
2170 (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE))
2173 #define granularity_align(S)\
2174 (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE))
2176 #define is_page_aligned(S)\
2177 (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
2178 #define is_granularity_aligned(S)\
2179 (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
2182 #define segment_holds(S, A)\
2183 ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
2189 msegmentptr sp = &
m->seg;
2193 if ((sp = sp->next) == 0)
2202 msegmentptr sp = &
m->seg;
2204 if ((
char *) sp >= ss->base && (
char *) sp < ss->
base + ss->size)
2206 if ((sp = sp->next) == 0)
2211 #ifndef MORECORE_CANNOT_TRIM
2212 #define should_trim(M,s) ((s) > (M)->trim_check)
2214 #define should_trim(M,s) (0)
2222 #define TOP_FOOT_SIZE\
2223 (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
2237 #define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams())
2239 #define PREACTION(M) ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
2240 #define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
2244 #define PREACTION(M) (0)
2248 #define POSTACTION(M)
2261 #if PROCEED_ON_ERROR
2264 int malloc_corruption_error_count;
2267 static void reset_on_error(mstate
m);
2269 #define CORRUPTION_ERROR_ACTION(m) reset_on_error(m)
2270 #define USAGE_ERROR_ACTION(m, p)
2274 #ifndef CORRUPTION_ERROR_ACTION
2275 #define CORRUPTION_ERROR_ACTION(m) ABORT
2278 #ifndef USAGE_ERROR_ACTION
2279 #define USAGE_ERROR_ACTION(m,p) ABORT
2288 #define check_free_chunk(M,P)
2289 #define check_inuse_chunk(M,P)
2290 #define check_malloced_chunk(M,P,N)
2291 #define check_mmapped_chunk(M,P)
2292 #define check_malloc_state(M)
2293 #define check_top_chunk(M,P)
2296 #define check_free_chunk(M,P) do_check_free_chunk(M,P)
2297 #define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P)
2298 #define check_top_chunk(M,P) do_check_top_chunk(M,P)
2299 #define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
2300 #define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P)
2301 #define check_malloc_state(M) do_check_malloc_state(M)
2303 static void do_check_any_chunk(mstate
m, mchunkptr
p);
2304 static void do_check_top_chunk(mstate
m, mchunkptr
p);
2305 static void do_check_mmapped_chunk(mstate
m, mchunkptr
p);
2306 static void do_check_inuse_chunk(mstate
m, mchunkptr
p);
2307 static void do_check_free_chunk(mstate
m, mchunkptr
p);
2308 static void do_check_malloced_chunk(mstate
m,
void *mem,
size_t s);
2309 static void do_check_tree(mstate
m, tchunkptr
t);
2310 static void do_check_treebin(mstate
m,
bindex_t i);
2311 static void do_check_smallbin(mstate
m,
bindex_t i);
2312 static void do_check_malloc_state(mstate
m);
2313 static int bin_find(mstate
m, mchunkptr
x);
2314 static size_t traverse_and_check(mstate
m);
2319 #define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
2320 #define small_index(s) ((s) >> SMALLBIN_SHIFT)
2321 #define small_index2size(i) ((i) << SMALLBIN_SHIFT)
2322 #define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE))
2325 #define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
2326 #define treebin_at(M,i) (&((M)->treebins[i]))
2329 #if defined(__GNUC__) && defined(i386)
2330 #define compute_tree_index(S, I)\
2332 size_t X = S >> TREEBIN_SHIFT;\
2335 else if (X > 0xFFFF)\
2339 __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm" (X));\
2340 I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
2344 #define compute_tree_index(S, I)\
2346 size_t X = S >> TREEBIN_SHIFT;\
2349 else if (X > 0xFFFF)\
2352 unsigned int Y = (unsigned int)X;\
2353 unsigned int N = ((Y - 0x100) >> 16) & 8;\
2354 unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
2356 N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
2357 K = 14 - N + ((Y <<= K) >> 15);\
2358 I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
2364 #define bit_for_tree_index(i) \
2365 (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
2368 #define leftshift_for_tree_index(i) \
2369 ((i == NTREEBINS-1)? 0 : \
2370 ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
2373 #define minsize_for_tree_index(i) \
2374 ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \
2375 (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
2381 #define idx2bit(i) ((binmap_t)(1) << (i))
2384 #define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i))
2385 #define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i))
2386 #define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i))
2388 #define mark_treemap(M,i) ((M)->treemap |= idx2bit(i))
2389 #define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i))
2390 #define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i))
2394 #if defined(__GNUC__) && defined(i386)
2395 #define compute_bit2idx(X, I)\
2398 __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\
2404 #define compute_bit2idx(X, I) I = ffs(X)-1
2407 #define compute_bit2idx(X, I)\
2409 unsigned int Y = X - 1;\
2410 unsigned int K = Y >> (16-4) & 16;\
2411 unsigned int N = K; Y >>= K;\
2412 N += K = Y >> (8-3) & 8; Y >>= K;\
2413 N += K = Y >> (4-2) & 4; Y >>= K;\
2414 N += K = Y >> (2-1) & 2; Y >>= K;\
2415 N += K = Y >> (1-0) & 1; Y >>= K;\
2416 I = (bindex_t)(N + Y);\
2422 #define least_bit(x) ((x) & -(x))
2425 #define left_bits(x) ((x<<1) | -(x<<1))
2428 #define same_or_left_bits(x) ((x) | -(x))
2461 #define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
2463 #define ok_next(p, n) ((char*)(p) < (char*)(n))
2465 #define ok_cinuse(p) cinuse(p)
2467 #define ok_pinuse(p) pinuse(p)
2470 #define ok_address(M, a) (1)
2471 #define ok_next(b, n) (1)
2472 #define ok_cinuse(p) (1)
2473 #define ok_pinuse(p) (1)
2476 #if (FOOTERS && !INSECURE)
2478 #define ok_magic(M) ((M)->magic == mparams.magic)
2480 #define ok_magic(M) (1)
2486 #if defined(__GNUC__) && __GNUC__ >= 3
2487 #define RTCHECK(e) __builtin_expect(e, 1)
2489 #define RTCHECK(e) (e)
2492 #define RTCHECK(e) (1)
2499 #define mark_inuse_foot(M,p,s)
2502 #define set_inuse(M,p,s)\
2503 ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
2504 ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
2507 #define set_inuse_and_pinuse(M,p,s)\
2508 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
2509 ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
2512 #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
2513 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
2518 #define mark_inuse_foot(M,p,s)\
2519 (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
2521 #define get_mstate_for(p)\
2522 ((mstate)(((mchunkptr)((char*)(p) +\
2523 (chunksize(p))))->prev_foot ^ mparams.magic))
2525 #define set_inuse(M,p,s)\
2526 ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
2527 (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
2528 mark_inuse_foot(M,p,s))
2530 #define set_inuse_and_pinuse(M,p,s)\
2531 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
2532 (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
2533 mark_inuse_foot(M,p,s))
2535 #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
2536 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
2537 mark_inuse_foot(M, p, s))
2552 #if MORECORE_CONTIGUOUS
2559 #if (FOOTERS && !INSECURE)
2565 if ((
fd = open(
"/dev/urandom", O_RDONLY)) >= 0 &&
2567 s = *((
size_t *)
buf);
2589 #if !defined(WIN32) && !defined(__OS2__)
2593 #elif defined (__OS2__)
2600 SYSTEM_INFO system_info;
2601 GetSystemInfo(&system_info);
2613 if ((
sizeof(
size_t) !=
sizeof(
char *)) ||
2615 (
sizeof(
int) < 4) ||
2632 switch (param_number) {
2655 do_check_any_chunk(mstate
m, mchunkptr
p)
2663 do_check_top_chunk(mstate
m, mchunkptr
p)
2679 do_check_mmapped_chunk(mstate
m, mchunkptr
p)
2695 do_check_inuse_chunk(mstate
m, mchunkptr
p)
2697 do_check_any_chunk(
m,
p);
2703 do_check_mmapped_chunk(
m,
p);
2708 do_check_free_chunk(mstate
m, mchunkptr
p)
2712 do_check_any_chunk(
m,
p);
2716 if (
p !=
m->dv &&
p !=
m->top) {
2720 assert(next->prev_foot == sz);
2732 do_check_malloced_chunk(mstate
m,
void *mem,
size_t s)
2737 do_check_inuse_chunk(
m,
p);
2748 do_check_tree(mstate
m, tchunkptr
t)
2763 do_check_any_chunk(
m, ((mchunkptr) u));
2764 assert(u->index == tindex);
2770 if (u->parent == 0) {
2771 assert(u->child[0] == 0);
2772 assert(u->child[1] == 0);
2777 assert(u->parent->child[0] == u ||
2778 u->parent->child[1] == u ||
2779 *((tbinptr *) (u->parent)) == u);
2780 if (u->child[0] != 0) {
2781 assert(u->child[0]->parent == u);
2782 assert(u->child[0] != u);
2783 do_check_tree(
m, u->child[0]);
2785 if (u->child[1] != 0) {
2786 assert(u->child[1]->parent == u);
2787 assert(u->child[1] != u);
2788 do_check_tree(
m, u->child[1]);
2790 if (u->child[0] != 0 && u->child[1] != 0) {
2805 int empty = (
m->treemap & (1U <<
i)) == 0;
2809 do_check_tree(
m,
t);
2817 mchunkptr
p =
b->
bk;
2818 unsigned int empty = (
m->smallmap & (1U <<
i)) == 0;
2822 for (;
p !=
b;
p =
p->bk) {
2826 do_check_free_chunk(
m,
p);
2833 do_check_inuse_chunk(
m,
q);
2840 bin_find(mstate
m, mchunkptr
x)
2851 }
while ((
p =
p->fd) !=
b);
2866 if (u == (tchunkptr)
x)
2868 }
while ((u = u->fd) !=
t);
2877 traverse_and_check(mstate
m)
2881 msegmentptr
s = &
m->seg;
2885 mchunkptr lastq = 0;
2892 do_check_inuse_chunk(
m,
q);
2896 do_check_free_chunk(
m,
q);
2909 do_check_malloc_state(mstate
m)
2915 do_check_smallbin(
m,
i);
2917 do_check_treebin(
m,
i);
2919 if (
m->dvsize != 0) {
2920 do_check_any_chunk(
m,
m->dv);
2927 do_check_top_chunk(
m,
m->top);
2933 total = traverse_and_check(
m);
2935 assert(
m->footprint <=
m->max_footprint);
2945 struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2952 msegmentptr
s = &
m->seg;
2970 nm.
hblkhd =
m->footprint - sum;
2987 #ifndef LACKS_STDIO_H
2994 msegmentptr
s = &
m->seg;
2995 #ifndef LACKS_STDIO_H
2996 maxfp =
m->max_footprint;
3012 #ifndef LACKS_STDIO_H
3013 fprintf(stderr,
"max system bytes = %10lu\n",
3014 (
unsigned long) (maxfp));
3015 fprintf(stderr,
"system bytes = %10lu\n", (
unsigned long) (fp));
3016 fprintf(stderr,
"in use bytes = %10lu\n", (
unsigned long) (used));
3033 #define insert_small_chunk(M, P, S) {\
3034 bindex_t I = small_index(S);\
3035 mchunkptr B = smallbin_at(M, I);\
3037 assert(S >= MIN_CHUNK_SIZE);\
3038 if (!smallmap_is_marked(M, I))\
3039 mark_smallmap(M, I);\
3040 else if (RTCHECK(ok_address(M, B->fd)))\
3043 CORRUPTION_ERROR_ACTION(M);\
3052 #define unlink_small_chunk(M, P, S) {\
3053 mchunkptr F = P->fd;\
3054 mchunkptr B = P->bk;\
3055 bindex_t I = small_index(S);\
3058 assert(chunksize(P) == small_index2size(I));\
3060 clear_smallmap(M, I);\
3061 else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\
3062 (B == smallbin_at(M,I) || ok_address(M, B)))) {\
3067 CORRUPTION_ERROR_ACTION(M);\
3072 #define unlink_first_small_chunk(M, B, P, I) {\
3073 mchunkptr F = P->fd;\
3076 assert(chunksize(P) == small_index2size(I));\
3078 clear_smallmap(M, I);\
3079 else if (RTCHECK(ok_address(M, F))) {\
3084 CORRUPTION_ERROR_ACTION(M);\
3090 #define replace_dv(M, P, S) {\
3091 size_t DVS = M->dvsize;\
3093 mchunkptr DV = M->dv;\
3094 assert(is_small(DVS));\
3095 insert_small_chunk(M, DV, DVS);\
3104 #define insert_large_chunk(M, X, S) {\
3107 compute_tree_index(S, I);\
3108 H = treebin_at(M, I);\
3110 X->child[0] = X->child[1] = 0;\
3111 if (!treemap_is_marked(M, I)) {\
3112 mark_treemap(M, I);\
3114 X->parent = (tchunkptr)H;\
3119 size_t K = S << leftshift_for_tree_index(I);\
3121 if (chunksize(T) != S) {\
3122 tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
3126 else if (RTCHECK(ok_address(M, C))) {\
3133 CORRUPTION_ERROR_ACTION(M);\
3138 tchunkptr F = T->fd;\
3139 if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
3147 CORRUPTION_ERROR_ACTION(M);\
3172 #define unlink_large_chunk(M, X) {\
3173 tchunkptr XP = X->parent;\
3176 tchunkptr F = X->fd;\
3178 if (RTCHECK(ok_address(M, F))) {\
3183 CORRUPTION_ERROR_ACTION(M);\
3188 if (((R = *(RP = &(X->child[1]))) != 0) ||\
3189 ((R = *(RP = &(X->child[0]))) != 0)) {\
3191 while ((*(CP = &(R->child[1])) != 0) ||\
3192 (*(CP = &(R->child[0])) != 0)) {\
3195 if (RTCHECK(ok_address(M, RP)))\
3198 CORRUPTION_ERROR_ACTION(M);\
3203 tbinptr* H = treebin_at(M, X->index);\
3205 if ((*H = R) == 0) \
3206 clear_treemap(M, X->index);\
3208 else if (RTCHECK(ok_address(M, XP))) {\
3209 if (XP->child[0] == X) \
3215 CORRUPTION_ERROR_ACTION(M);\
3217 if (RTCHECK(ok_address(M, R))) {\
3220 if ((C0 = X->child[0]) != 0) {\
3221 if (RTCHECK(ok_address(M, C0))) {\
3226 CORRUPTION_ERROR_ACTION(M);\
3228 if ((C1 = X->child[1]) != 0) {\
3229 if (RTCHECK(ok_address(M, C1))) {\
3234 CORRUPTION_ERROR_ACTION(M);\
3238 CORRUPTION_ERROR_ACTION(M);\
3245 #define insert_chunk(M, P, S)\
3246 if (is_small(S)) insert_small_chunk(M, P, S)\
3247 else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
3249 #define unlink_chunk(M, P, S)\
3250 if (is_small(S)) unlink_small_chunk(M, P, S)\
3251 else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
3257 #define internal_malloc(m, b) mspace_malloc(m, b)
3258 #define internal_free(m, mem) mspace_free(m,mem);
3261 #define internal_malloc(m, b)\
3262 (m == gm)? dlmalloc(b) : mspace_malloc(m, b)
3263 #define internal_free(m, mem)\
3264 if (m == gm) dlfree(mem); else mspace_free(m,mem);
3266 #define internal_malloc(m, b) dlmalloc(b)
3267 #define internal_free(m, mem) dlfree(mem)
3294 mchunkptr
p = (mchunkptr) (mm +
offset);
3301 if (mm < m->least_addr)
3303 if ((
m->footprint += mmsize) >
m->max_footprint)
3304 m->max_footprint =
m->footprint;
3330 oldmmsize, newmmsize, 1);
3332 mchunkptr newp = (mchunkptr) (
cp +
offset);
3339 if (cp < m->least_addr)
3341 if ((
m->footprint += newmmsize - oldmmsize) >
m->max_footprint)
3342 m->max_footprint =
m->footprint;
3358 p = (mchunkptr) ((
char *)
p +
offset);
3377 bin->fd = bin->bk = bin;
3381 #if PROCEED_ON_ERROR
3385 reset_on_error(mstate
m)
3388 ++malloc_corruption_error_count;
3390 m->smallbins =
m->treebins = 0;
3391 m->dvsize =
m->topsize = 0;
3408 size_t psize = (
char *) oldfirst - (
char *)
p;
3410 size_t qsize = psize - nb;
3413 assert((
char *) oldfirst > (
char *)
q);
3418 if (oldfirst ==
m->top) {
3419 size_t tsize =
m->topsize += qsize;
3423 }
else if (oldfirst ==
m->dv) {
3424 size_t dsize =
m->dvsize += qsize;
3449 char *old_top = (
char *)
m->top;
3451 char *old_end = oldsp->base + oldsp->size;
3455 char *asp = rawsp +
offset;
3457 mchunkptr sp = (mchunkptr) csp;
3458 msegmentptr ss = (msegmentptr) (
chunk2mem(sp));
3460 mchunkptr
p = tnext;
3470 m->seg.base = tbase;
3471 m->seg.size = tsize;
3472 m->seg.sflags = mmapped;
3480 if ((
char *) (&(nextp->head)) < old_end)
3488 if (csp != old_top) {
3489 mchunkptr
q = (mchunkptr) old_top;
3490 size_t psize = csp - old_top;
3626 size_t ssize =
end - br;
3637 if ((
m->footprint += tsize) >
m->max_footprint)
3638 m->max_footprint =
m->footprint;
3641 m->seg.base =
m->least_addr = tbase;
3642 m->seg.size = tsize;
3643 m->seg.sflags = mmap_flag;
3652 (
size_t) ((tbase + tsize) - (
char *) mn) -
3659 msegmentptr sp = &
m->seg;
3660 while (sp != 0 && tbase != sp->base + sp->size)
3666 if (tbase < m->least_addr)
3667 m->least_addr = tbase;
3669 while (sp != 0 && sp->base != tbase + tsize)
3674 char *oldbase = sp->base;
3683 if (nb < m->topsize) {
3684 size_t rsize =
m->topsize -= nb;
3685 mchunkptr
p =
m->top;
3705 size_t released = 0;
3706 msegmentptr pred = &
m->seg;
3707 msegmentptr sp = pred->
next;
3709 char *
base = sp->base;
3710 size_t size = sp->size;
3711 msegmentptr next = sp->
next;
3718 tchunkptr tp = (tchunkptr)
p;
3728 m->footprint -=
size;
3746 size_t released = 0;
3750 if (
m->topsize > pad) {
3753 size_t extra = ((
m->topsize - pad + (unit -
SIZE_T_ONE)) / unit -
3760 size_t newsize = sp->size - extra;
3762 if ((
CALL_MREMAP(sp->base, sp->size, newsize, 0) !=
3764 || (
CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
3775 if (old_br == sp->base + sp->size) {
3778 if (rel_br !=
CMFAIL && new_br < old_br)
3779 released = old_br - new_br;
3786 if (released != 0) {
3787 sp->size -= released;
3788 m->footprint -= released;
3803 return (released != 0) ? 1 : 0;
3827 if ((rsize = trem) == 0)
3832 if (rt != 0 && rt !=
t)
3842 if (
t == 0 &&
v == 0) {
3844 if (leftbits != 0) {
3862 if (
v != 0 && rsize < (
size_t) (
m->dvsize - nb)) {
3947 else if (oldsize >= nb) {
3948 size_t rsize = oldsize - nb;
3956 }
else if (next ==
m->top && oldsize +
m->topsize > nb) {
3958 size_t newsize = oldsize +
m->topsize;
3959 size_t newtopsize = newsize - nb;
3964 m->topsize = newtopsize;
3985 memcpy(newmem, oldmem, (oc < bytes) ? oc : bytes);
4003 if ((alignment & (alignment -
SIZE_T_ONE)) != 0) {
4005 while (
a < alignment)
4025 if ((((
size_t) (mem)) % alignment) != 0) {
4039 ((
size_t) (br - (
char *) (
p)) >=
4041 mchunkptr newp = (mchunkptr) pos;
4042 size_t leadsize = pos - (
char *) (
p);
4046 newp->prev_foot =
p->prev_foot + leadsize;
4060 size_t remainder_size =
size - nb;
4087 ialloc(mstate
m,
size_t n_elements,
size_t *
sizes,
int opts,
void *chunks[])
4098 size_t element_size;
4099 size_t contents_size;
4103 size_t remainder_size;
4105 mchunkptr array_chunk;
4112 if (n_elements == 0)
4118 if (n_elements == 0)
4121 array_size =
request2size(n_elements * (
sizeof(
void *)));
4127 contents_size = n_elements * element_size;
4131 for (
i = 0;
i != n_elements; ++
i)
4135 size = contents_size + array_size;
4163 size_t array_chunk_size;
4165 array_chunk_size = remainder_size - contents_size;
4166 marray = (
void **) (
chunk2mem(array_chunk));
4168 remainder_size = contents_size;
4174 if (
i != n_elements - 1) {
4175 if (element_size != 0)
4176 size = element_size;
4179 remainder_size -=
size;
4189 if (marray != chunks) {
4191 if (element_size != 0) {
4192 assert(remainder_size == element_size);
4198 for (
i = 0;
i != n_elements; ++
i)
4246 smallbits =
gm->smallmap >>
idx;
4248 if ((smallbits & 0x3U) != 0) {
4250 idx += ~smallbits & 1;
4261 else if (nb >
gm->dvsize) {
4262 if (smallbits != 0) {
4289 else if (
gm->treemap != 0
4305 if (nb <= gm->dvsize) {
4306 size_t rsize =
gm->dvsize - nb;
4307 mchunkptr
p =
gm->dv;
4314 size_t dvs =
gm->dvsize;
4324 else if (nb < gm->topsize) {
4325 size_t rsize =
gm->topsize -= nb;
4326 mchunkptr
p =
gm->top;
4358 mstate
fm = get_mstate_for(
p);
4372 size_t prevsize =
p->prev_foot;
4377 fm->footprint -= psize;
4399 if (next ==
fm->top) {
4400 size_t tsize =
fm->topsize += psize;
4410 }
else if (next ==
fm->dv) {
4411 size_t dsize =
fm->dvsize += psize;
4448 if (n_elements != 0) {
4450 if (((n_elements |
elem_size) & ~(
size_t) 0xffff) &&
4465 #ifdef REALLOC_ZERO_BYTES_FREES
4475 mstate
m = get_mstate_for(
mem2chunk(oldmem));
4495 return ialloc(
gm, n_elements, &sz, 3, chunks);
4537 return gm->footprint;
4543 return gm->max_footprint;
4584 init_user_mstate(
char *tbase,
size_t tsize)
4593 m->seg.base =
m->least_addr = tbase;
4594 m->seg.size =
m->footprint =
m->max_footprint = tsize;
4606 create_mspace(
size_t capacity,
int locked)
4616 char *tbase = (
char *) (
CALL_MMAP(tsize));
4618 m = init_user_mstate(tbase, tsize);
4627 create_mspace_with_base(
void *
base,
size_t capacity,
int locked)
4635 m = init_user_mstate((
char *)
base, capacity);
4643 destroy_mspace(mspace msp)
4646 mstate ms = (mstate) msp;
4648 msegmentptr sp = &ms->seg;
4650 char *
base = sp->base;
4651 size_t size = sp->size;
4652 flag_t flag = sp->sflags;
4671 mspace_malloc(mspace msp,
size_t bytes)
4673 mstate ms = (mstate) msp;
4686 smallbits = ms->smallmap >>
idx;
4688 if ((smallbits & 0x3U) != 0) {
4690 idx += ~smallbits & 1;
4701 else if (nb > ms->dvsize) {
4702 if (smallbits != 0) {
4729 else if (ms->treemap != 0
4739 if (ms->treemap != 0 && (mem =
tmalloc_large(ms, nb)) != 0) {
4745 if (nb <= ms->dvsize) {
4746 size_t rsize = ms->dvsize - nb;
4747 mchunkptr
p = ms->dv;
4754 size_t dvs = ms->dvsize;
4764 else if (nb < ms->topsize) {
4765 size_t rsize = ms->topsize -= nb;
4766 mchunkptr
p = ms->top;
4787 mspace_free(mspace msp,
void *mem)
4792 mstate
fm = get_mstate_for(
p);
4794 mstate
fm = (mstate) msp;
4806 size_t prevsize =
p->prev_foot;
4811 fm->footprint -= psize;
4833 if (next ==
fm->top) {
4834 size_t tsize =
fm->topsize += psize;
4844 }
else if (next ==
fm->dv) {
4845 size_t dsize =
fm->dvsize += psize;
4875 mspace_calloc(mspace msp,
size_t n_elements,
size_t elem_size)
4879 mstate ms = (mstate) msp;
4884 if (n_elements != 0) {
4886 if (((n_elements |
elem_size) & ~(
size_t) 0xffff) &&
4897 mspace_realloc(mspace msp,
void *oldmem,
size_t bytes)
4900 return mspace_malloc(msp, bytes);
4901 #ifdef REALLOC_ZERO_BYTES_FREES
4903 mspace_free(msp, oldmem);
4910 mstate ms = get_mstate_for(
p);
4912 mstate ms = (mstate) msp;
4923 mspace_memalign(mspace msp,
size_t alignment,
size_t bytes)
4925 mstate ms = (mstate) msp;
4934 mspace_independent_calloc(mspace msp,
size_t n_elements,
4938 mstate ms = (mstate) msp;
4943 return ialloc(ms, n_elements, &sz, 3, chunks);
4947 mspace_independent_comalloc(mspace msp,
size_t n_elements,
4948 size_t sizes[],
void *chunks[])
4950 mstate ms = (mstate) msp;
4959 mspace_trim(mspace msp,
size_t pad)
4962 mstate ms = (mstate) msp;
4975 mspace_malloc_stats(mspace msp)
4977 mstate ms = (mstate) msp;
4986 mspace_footprint(mspace msp)
4989 mstate ms = (mstate) msp;
4999 mspace_max_footprint(mspace msp)
5002 mstate ms = (mstate) msp;
5013 mspace_mallinfo(mspace msp)
5015 mstate ms = (mstate) msp;
5024 mspace_mallopt(
int param_number,
int value)
5307 #define real_malloc malloc
5308 #define real_calloc calloc
5309 #define real_realloc realloc
5310 #define real_free free
5312 #define real_malloc dlmalloc
5313 #define real_calloc dlcalloc
5314 #define real_realloc dlrealloc
5315 #define real_free dlfree
5398 if (!nmemb || !
size) {
void *(* SDL_realloc_func)(void *mem, size_t size)
SDL_atomic_t num_allocations
#define compute_tree_index(S, I)
MALLINFO_FIELD_TYPE fordblks
static msegmentptr segment_holding(mstate m, char *addr)
#define set_free_with_pinuse(p, s, n)
void *(* SDL_calloc_func)(size_t nmemb, size_t size)
EGLSurface EGLnsecsANDROID time
#define CALL_MUNMAP(a, s)
SDL_calloc_func calloc_func
static int has_segment_link(mstate m, msegmentptr ss)
#define insert_chunk(M, P, S)
void(* SDL_free_func)(void *mem)
#define request2size(req)
#define check_top_chunk(M, P)
#define CORRUPTION_ERROR_ACTION(m)
GLboolean GLboolean GLboolean b
void * dlmemalign(size_t, size_t)
SDL_malloc_func malloc_func
#define MORECORE_CONTIGUOUS
int SDL_GetNumAllocations(void)
Get the number of outstanding (unfreed) allocations.
#define treemap_is_marked(M, i)
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst base
#define is_extern_segment(S)
set set set set set set set macro pixldst1 elem_size
#define calloc_must_clear(p)
GLdouble GLdouble GLdouble GLdouble q
GLdouble GLdouble GLdouble r
#define granularity_align(S)
#define unlink_large_chunk(M, X)
#define SDL_InvalidParamError(param)
#define SDL_AtomicIncRef(a)
Increment an atomic variable used as a reference count.
static int change_mparam(int param_number, int value)
static void win32_release_lock(MLOCK_T *sl)
void * SDL_realloc(void *ptr, size_t size)
#define MAX_SMALL_REQUEST
#define segment_holds(S, A)
static int sys_trim(mstate m, size_t pad)
GLuint GLfloat GLfloat GLfloat x1
GLboolean GLboolean GLboolean GLboolean a
static void init_bins(mstate m)
static size_t release_unused_segments(mstate m)
void * dlcalloc(size_t, size_t)
#define check_free_chunk(M, P)
#define RELEASE_MAGIC_INIT_LOCK()
#define minsize_for_tree_index(i)
#define USE_NONCONTIGUOUS_BIT
static int win32munmap(void *ptr, size_t size)
size_t dlmalloc_footprint(void)
#define SDL_AtomicDecRef(a)
Decrement an atomic variable used as a reference count.
static void * tmalloc_large(mstate m, size_t nb)
#define set_size_and_pinuse_of_free_chunk(p, s)
#define USAGE_ERROR_ACTION(m, p)
#define unlink_first_small_chunk(M, B, P, I)
GLenum GLuint GLenum GLsizei const GLchar * buf
#define set_size_and_pinuse_of_inuse_chunk(M, p, s)
int SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, SDL_calloc_func calloc_func, SDL_realloc_func realloc_func, SDL_free_func free_func)
Replace SDL's memory allocation functions with a custom set.
#define MALLINFO_FIELD_TYPE
static void add_segment(mstate m, char *tbase, size_t tsize, flag_t mmapped)
void ** dlindependent_calloc(size_t, size_t, void **)
#define FOUR_SIZE_T_SIZES
#define unlink_chunk(M, P, S)
GLint GLint GLint GLint GLint x
#define check_malloc_state(M)
static void init_top(mstate m, mchunkptr p, size_t psize)
static void * internal_realloc(mstate m, void *oldmem, size_t bytes)
#define check_mmapped_chunk(M, P)
static int init_mparams(void)
MALLINFO_FIELD_TYPE hblkhd
size_t dlmalloc_usable_size(void *)
static void * sys_alloc(mstate m, size_t nb)
struct mallinfo dlmallinfo(void)
#define check_inuse_chunk(M, P)
#define DEFAULT_MMAP_THRESHOLD
MALLINFO_FIELD_TYPE ordblks
#define insert_large_chunk(M, X, S)
size_t dlmalloc_max_footprint(void)
#define set_inuse_and_pinuse(M, p, s)
#define set_inuse(M, p, s)
#define chunk_minus_offset(p, s)
MALLINFO_FIELD_TYPE uordblks
MALLINFO_FIELD_TYPE fsmblks
struct malloc_tree_chunk * parent
MALLINFO_FIELD_TYPE usmblks
struct malloc_tree_chunk * bk
#define disable_contiguous(M)
static void * win32direct_mmap(size_t size)
void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, SDL_calloc_func *calloc_func, SDL_realloc_func *realloc_func, SDL_free_func *free_func)
Get the current set of SDL memory functions.
#define internal_free(m, mem)
static MLOCK_T magic_init_mutex
MALLINFO_FIELD_TYPE hblks
static void * win32mmap(size_t size)
static void * tmalloc_small(mstate m, size_t nb)
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
void dlmalloc_stats(void)
static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb)
static void internal_malloc_stats(mstate m)
#define DEFAULT_TRIM_THRESHOLD
void *(* SDL_malloc_func)(size_t size)
MALLINFO_FIELD_TYPE smblks
#define use_noncontiguous(M)
#define chunk_plus_offset(p, s)
#define is_initialized(M)
GLsizei const GLfloat * value
static struct malloc_params mparams
#define check_malloced_chunk(M, P, N)
#define leftmost_child(t)
#define should_trim(M, s)
static void ** ialloc(mstate m, size_t n_elements, size_t *sizes, int opts, void *chunks[])
#define ACQUIRE_MORECORE_LOCK()
#define ACQUIRE_MAGIC_INIT_LOCK()
static struct mallinfo internal_mallinfo(mstate m)
static int win32_acquire_lock(MLOCK_T *sl)
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...
#define replace_dv(M, P, S)
struct malloc_segment * next
#define internal_malloc(m, b)
tbinptr treebins[NTREEBINS]
MALLINFO_FIELD_TYPE arena
void * SDL_malloc(size_t size)
#define small_index2size(i)
mchunkptr smallbins[(NSMALLBINS+1) *2]
#define smallbin_at(M, i)
SDL_realloc_func realloc_func
struct malloc_tree_chunk * fd
MALLINFO_FIELD_TYPE keepcost
#define MALLOC_FAILURE_ACTION
void ** dlindependent_comalloc(size_t, size_t *, void **)
static void * internal_memalign(mstate m, size_t alignment, size_t bytes)
#define is_mmapped_segment(S)
struct malloc_tree_chunk * child[2]
#define mark_inuse_foot(M, p, s)
#define align_as_chunk(A)
#define RELEASE_MORECORE_LOCK()
int dlmalloc_trim(size_t)
void * SDL_calloc(size_t nmemb, size_t size)
#define compute_bit2idx(X, I)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
static void * prepend_alloc(mstate m, char *newbase, char *oldbase, size_t nb)
#define leftshift_for_tree_index(i)
static struct malloc_state _gm_
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
static void * mmap_alloc(mstate m, size_t nb)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 idx
void * dlrealloc(void *, size_t)
#define CALL_MREMAP(addr, osz, nsz, mv)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#define DEFAULT_GRANULARITY
#define is_page_aligned(S)
#define smallmap_is_marked(M, i)