The R Project SVN R

Rev

Rev 68538 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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