ยปCore Development>Code coverage>Modules/_ctypes/libffi/src/dlmalloc.c

Python code coverage for Modules/_ctypes/libffi/src/dlmalloc.c

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