bca68e8abebe06d636677f4be9a8d4a1e59fc96a
[platform/upstream/bash.git] / lib / malloc / malloc.c
1 /* malloc.c - dynamic memory allocation for bash. */
2
3 /*  Copyright (C) 1985-2005 Free Software Foundation, Inc.
4
5     This file is part of GNU Bash, the Bourne-Again SHell.
6     
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /*
22  * @(#)nmalloc.c 1 (Caltech) 2/21/82
23  *
24  *      U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
25  *
26  *      Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
27  *
28  * This is a very fast storage allocator.  It allocates blocks of a small 
29  * number of different sizes, and keeps free lists of each size.  Blocks
30  * that don't exactly fit are passed up to the next larger size.  In this 
31  * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
32  * This is designed for use in a program that uses vast quantities of
33  * memory, but bombs when it runs out.  To make it a little better, it
34  * warns the user when he starts to get near the end.
35  *
36  * June 84, ACT: modified rcheck code to check the range given to malloc,
37  * rather than the range determined by the 2-power used.
38  *
39  * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
40  * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
41  * You should call malloc_init to reinitialize after loading dumped Emacs.
42  * Call malloc_stats to get info on memory stats if MALLOC_STATS turned on.
43  * realloc knows how to return same block given, just changing its size,
44  * if the power of 2 is correct.
45  */
46
47 /*
48  * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
49  * smallest allocatable block is 8 bytes.  The overhead information will
50  * go in the first int of the block, and the returned pointer will point
51  * to the second.
52  */
53
54 /* Define MEMSCRAMBLE to have free() write 0xcf into memory as it's freed, to
55    uncover callers that refer to freed memory, and to have malloc() write 0xdf
56    into memory as it's allocated to avoid referring to previous contents. */
57
58 /* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE;
59    handled by configure. */
60
61 #if defined (HAVE_CONFIG_H)
62 #  include <config.h>
63 #endif /* HAVE_CONFIG_H */
64
65 #if defined (SHELL)
66 #  include "bashtypes.h"
67 #  include "stdc.h"
68 #else
69 #  include <sys/types.h>
70 #endif
71
72 #if defined (HAVE_UNISTD_H)
73 #  include <unistd.h>
74 #endif
75
76 /* Determine which kind of system this is.  */
77 #include <signal.h>
78
79 #if defined (HAVE_STRING_H)
80 #  include <string.h>
81 #else
82 #  include <strings.h>
83 #endif
84
85 #include <stdio.h>
86
87 /* Define getpagesize () if the system does not.  */
88 #ifndef HAVE_GETPAGESIZE
89 #  include "getpagesize.h"
90 #endif
91
92 #include "imalloc.h"
93 #ifdef MALLOC_STATS
94 #  include "mstats.h"
95 #endif
96 #ifdef MALLOC_REGISTER
97 #  include "table.h"
98 #endif
99 #ifdef MALLOC_WATCH
100 #  include "watch.h"
101 #endif
102
103 /* System-specific omissions. */
104 #ifdef HPUX
105 #  define NO_VALLOC
106 #endif
107
108 #define NBUCKETS        30
109
110 #define ISALLOC ((char) 0xf7)   /* magic byte that implies allocation */
111 #define ISFREE ((char) 0x54)    /* magic byte that implies free block */
112                                 /* this is for error checking only */
113 #define ISMEMALIGN ((char) 0xd6)  /* Stored before the value returned by
114                                      memalign, with the rest of the word
115                                      being the distance to the true
116                                      beginning of the block.  */
117
118
119 /* We have a flag indicating whether memory is allocated, an index in
120    nextf[], a size field, and a sentinel value to determine whether or
121    not a caller wrote before the start of allocated memory; to realloc()
122    memory we either copy mh_nbytes or just change mh_nbytes if there is
123    enough room in the block for the new size.  Range checking is always
124    done. */
125 union mhead {
126   bits64_t mh_align;                                            /* 8 */
127   struct {
128     char mi_alloc;              /* ISALLOC or ISFREE */         /* 1 */
129     char mi_index;              /* index in nextf[] */          /* 1 */
130     /* Remainder are valid only when block is allocated */
131     u_bits16_t mi_magic2;       /* should be == MAGIC2 */       /* 2 */
132     u_bits32_t mi_nbytes;       /* # of bytes allocated */      /* 4 */
133   } minfo;
134 };
135 #define mh_alloc        minfo.mi_alloc
136 #define mh_index        minfo.mi_index
137 #define mh_nbytes       minfo.mi_nbytes
138 #define mh_magic2       minfo.mi_magic2
139
140 #define MOVERHEAD       sizeof(union mhead)
141 #define MALIGN_MASK     7       /* one less than desired alignment */
142
143 typedef union _malloc_guard {
144   char s[4];
145   u_bits32_t i;
146 } mguard_t;
147
148 /* Access free-list pointer of a block.
149    It is stored at block + sizeof (char *).
150    This is not a field in the minfo structure member of union mhead
151    because we want sizeof (union mhead)
152    to describe the overhead for when the block is in use,
153    and we do not want the free-list pointer to count in that.  */
154
155 #define CHAIN(a) \
156   (*(union mhead **) (sizeof (char *) + (char *) (a)))
157
158 /* To implement range checking, we write magic values in at the beginning
159    and end of each allocated block, and make sure they are undisturbed
160    whenever a free or a realloc occurs. */
161
162 /* Written in the 2 bytes before the block's real space (-4 bytes) */
163 #define MAGIC2 0x5555
164 #define MSLOP  4                /* 4 bytes extra for u_bits32_t size */
165
166 /* How many bytes are actually allocated for a request of size N --
167    rounded up to nearest multiple of 8 after accounting for malloc
168    overhead. */
169 #define ALLOCATED_BYTES(n) \
170         (((n) + MOVERHEAD + MSLOP + MALIGN_MASK) & ~MALIGN_MASK)
171
172 #define ASSERT(p) \
173   do \
174     { \
175       if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, __STRING(p), file, line); \
176     } \
177   while (0)
178
179 /* Minimum and maximum bucket indices for block splitting (and to bound
180    the search for a block to split). */
181 #define SPLIT_MIN       2       /* XXX - was 3 */
182 #define SPLIT_MID       11
183 #define SPLIT_MAX       14
184
185 /* Minimum and maximum bucket indices for block coalescing. */
186 #define COMBINE_MIN     2
187 #define COMBINE_MAX     (pagebucket - 1)        /* XXX */
188
189 #define LESSCORE_MIN    10
190 #define LESSCORE_FRC    13
191
192 #define STARTBUCK       1
193
194 /* Flags for the internal functions. */
195 #define MALLOC_WRAPPER  0x01    /* wrapper function */
196 #define MALLOC_INTERNAL 0x02    /* internal function calling another */
197 #define MALLOC_NOTRACE  0x04    /* don't trace this allocation or free */
198 #define MALLOC_NOREG    0x08    /* don't register this allocation or free */
199
200 /* Future use. */
201 #define ERR_DUPFREE             0x01
202 #define ERR_UNALLOC             0x02
203 #define ERR_UNDERFLOW           0x04    
204 #define ERR_ASSERT_FAILED       0x08
205
206 /* Evaluates to true if NB is appropriate for bucket NU.  NB is adjusted
207    appropriately by the caller to account for malloc overhead.  This only
208    checks that the recorded size is not too big for the bucket.  We
209    can't check whether or not it's in between NU and NU-1 because we
210    might have encountered a busy bucket when allocating and moved up to
211    the next size. */
212 #define IN_BUCKET(nb, nu)       ((nb) <= binsizes[(nu)])
213
214 /* Use this when we want to be sure that NB is in bucket NU. */
215 #define RIGHT_BUCKET(nb, nu) \
216         (((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))
217
218 /* nextf[i] is free list of blocks of size 2**(i + 3)  */
219
220 static union mhead *nextf[NBUCKETS];
221
222 /* busy[i] is nonzero while allocation or free of block size i is in progress. */
223
224 static char busy[NBUCKETS];
225
226 static int pagesz;      /* system page size. */
227 static int pagebucket;  /* bucket for requests a page in size */
228 static int maxbuck;     /* highest bucket receiving allocation request. */
229
230 static char *memtop;    /* top of heap */
231
232 static const unsigned long binsizes[NBUCKETS] = {
233         8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
234         8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
235         1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
236         67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
237         2147483648UL, 4294967295UL
238 };
239
240 /* binsizes[x] == (1 << ((x) + 3)) */
241 #define binsize(x)      binsizes[(x)]
242
243 /* Declarations for internal functions */
244 static PTR_T internal_malloc __P((size_t, const char *, int, int));
245 static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
246 static void internal_free __P((PTR_T, const char *, int, int));
247 static PTR_T internal_memalign __P((size_t, size_t, const char *, int, int));
248 #ifndef NO_CALLOC
249 static PTR_T internal_calloc __P((size_t, size_t, const char *, int, int));
250 static void internal_cfree __P((PTR_T, const char *, int, int));
251 #endif
252 #ifndef NO_VALLOC
253 static PTR_T internal_valloc __P((size_t, const char *, int, int));
254 #endif
255
256 #if defined (botch)
257 extern void botch ();
258 #else
259 static void botch __P((const char *, const char *, int));
260 #endif
261 static void xbotch __P((PTR_T, int, const char *, const char *, int));
262
263 #if !HAVE_DECL_SBRK
264 extern char *sbrk ();
265 #endif /* !HAVE_DECL_SBRK */
266
267 #ifdef SHELL
268 extern int interrupt_immediately;
269 extern int signal_is_trapped __P((int));
270 #endif
271
272 #ifdef MALLOC_STATS
273 struct _malstats _mstats;
274 #endif /* MALLOC_STATS */
275
276 /* Debugging variables available to applications. */
277 int malloc_flags = 0;   /* future use */
278 int malloc_trace = 0;   /* trace allocations and frees to stderr */
279 int malloc_register = 0;        /* future use */
280
281 #ifdef MALLOC_TRACE
282 char _malloc_trace_buckets[NBUCKETS];
283
284 /* These should really go into a header file. */
285 extern void mtrace_alloc __P((const char *, PTR_T, size_t, const char *, int));
286 extern void mtrace_free __P((PTR_T, int, const char *, int));
287 #endif
288
289 #if !defined (botch)
290 static void
291 botch (s, file, line)
292      const char *s;
293      const char *file;
294      int line;
295 {
296   fprintf (stderr, _("malloc: failed assertion: %s\n"), s);
297   (void)fflush (stderr);
298   abort ();
299 }
300 #endif
301
302 /* print the file and line number that caused the assertion failure and
303    call botch() to do whatever the application wants with the information */
304 static void
305 xbotch (mem, e, s, file, line)
306      PTR_T mem;
307      int e;
308      const char *s;
309      const char *file;
310      int line;
311 {
312   fprintf (stderr, _("\r\nmalloc: %s:%d: assertion botched\r\n"),
313                         file ? file : _("unknown"), line);
314 #ifdef MALLOC_REGISTER
315   if (mem != NULL && malloc_register)
316     mregister_describe_mem (mem, stderr);
317 #endif
318   (void)fflush (stderr);
319   botch(s, file, line);
320 }
321
322 /* Coalesce two adjacent free blocks off the free list for size NU - 1,
323    as long as we can find two adjacent free blocks.  nextf[NU -1] is
324    assumed to not be busy; the caller (morecore()) checks for this. 
325    BUSY[NU] must be set to 1. */
326 static void
327 bcoalesce (nu)
328      register int nu;
329 {
330   register union mhead *mp, *mp1, *mp2;
331   register int nbuck;
332   unsigned long siz;
333
334   nbuck = nu - 1;
335   if (nextf[nbuck] == 0 || busy[nbuck])
336     return;
337
338   busy[nbuck] = 1;
339   siz = binsize (nbuck);
340
341   mp2 = mp1 = nextf[nbuck];
342   mp = CHAIN (mp1);
343   while (mp && mp != (union mhead *)((char *)mp1 + siz))
344     {
345       mp2 = mp1;
346       mp1 = mp;
347       mp = CHAIN (mp);
348     }
349
350   if (mp == 0)
351     {
352       busy[nbuck] = 0;
353       return;
354     }
355
356   /* OK, now we have mp1 pointing to the block we want to add to nextf[NU].
357      CHAIN(mp2) must equal mp1.  Check that mp1 and mp are adjacent. */
358   if (mp2 != mp1 && CHAIN(mp2) != mp1)
359     {
360       busy[nbuck] = 0;
361       xbotch ((PTR_T)0, 0, "bcoalesce: CHAIN(mp2) != mp1", (char *)NULL, 0);
362     }
363
364 #ifdef MALLOC_DEBUG
365   if (CHAIN (mp1) != (union mhead *)((char *)mp1 + siz))
366     {
367       busy[nbuck] = 0;
368       return;   /* not adjacent */
369     }
370 #endif
371
372   /* Since they are adjacent, remove them from the free list */
373   if (mp1 == nextf[nbuck])
374     nextf[nbuck] = CHAIN (mp);
375   else
376     CHAIN (mp2) = CHAIN (mp);
377   busy[nbuck] = 0;
378
379 #ifdef MALLOC_STATS
380   _mstats.tbcoalesce++;
381   _mstats.ncoalesce[nbuck]++;
382 #endif
383
384   /* And add the combined two blocks to nextf[NU]. */
385   mp1->mh_alloc = ISFREE;
386   mp1->mh_index = nu;
387   CHAIN (mp1) = nextf[nu];
388   nextf[nu] = mp1;
389 }
390
391 /* Split a block at index > NU (but less than SPLIT_MAX) into a set of
392    blocks of the correct size, and attach them to nextf[NU].  nextf[NU]
393    is assumed to be empty.  Must be called with signals blocked (e.g.,
394    by morecore()).  BUSY[NU] must be set to 1. */
395 static void
396 bsplit (nu)
397      register int nu;
398 {
399   register union mhead *mp;
400   int nbuck, nblks, split_max;
401   unsigned long siz;
402
403   split_max = (maxbuck > SPLIT_MAX) ? maxbuck : SPLIT_MAX;
404
405   if (nu >= SPLIT_MID)
406     {
407       for (nbuck = split_max; nbuck > nu; nbuck--)
408         {
409           if (busy[nbuck] || nextf[nbuck] == 0)
410             continue;
411           break;
412         }
413     }
414   else
415     {
416       for (nbuck = nu + 1; nbuck <= split_max; nbuck++)
417         {
418           if (busy[nbuck] || nextf[nbuck] == 0)
419             continue;
420           break;
421         }
422     }
423
424   if (nbuck > split_max || nbuck <= nu)
425     return;
426
427   /* XXX might want to split only if nextf[nbuck] has >= 2 blocks free
428      and nbuck is below some threshold. */
429
430   /* Remove the block from the chain of larger blocks. */
431   busy[nbuck] = 1;
432   mp = nextf[nbuck];
433   nextf[nbuck] = CHAIN (mp);
434   busy[nbuck] = 0;
435
436 #ifdef MALLOC_STATS
437   _mstats.tbsplit++;
438   _mstats.nsplit[nbuck]++;
439 #endif
440
441   /* Figure out how many blocks we'll get. */
442   siz = binsize (nu);
443   nblks = binsize (nbuck) / siz;
444
445   /* Split the block and put it on the requested chain. */
446   nextf[nu] = mp;
447   while (1)
448     {
449       mp->mh_alloc = ISFREE;
450       mp->mh_index = nu;
451       if (--nblks <= 0) break;
452       CHAIN (mp) = (union mhead *)((char *)mp + siz);
453       mp = (union mhead *)((char *)mp + siz);
454     }
455   CHAIN (mp) = 0;
456 }
457
458 /* Take the memory block MP and add it to a chain < NU.  NU is the right bucket,
459    but is busy.  This avoids memory orphaning. */
460 static void
461 xsplit (mp, nu)
462      union mhead *mp;
463      int nu;
464 {
465   union mhead *nh;
466   int nbuck, nblks, split_max;
467   unsigned long siz;
468
469   nbuck = nu - 1;
470   while (nbuck >= SPLIT_MIN && busy[nbuck])
471     nbuck--;
472   if (nbuck < SPLIT_MIN)
473     return;
474
475 #ifdef MALLOC_STATS
476   _mstats.tbsplit++;
477   _mstats.nsplit[nu]++;
478 #endif
479
480   /* Figure out how many blocks we'll get. */
481   siz = binsize (nu);                   /* original block size */
482   nblks = siz / binsize (nbuck);        /* should be 2 most of the time */
483
484   /* And add it to nextf[nbuck] */
485   siz = binsize (nbuck);                /* XXX - resetting here */
486   nh = mp;
487   while (1)
488     {
489       mp->mh_alloc = ISFREE;
490       mp->mh_index = nbuck;
491       if (--nblks <= 0) break;
492       CHAIN (mp) = (union mhead *)((char *)mp + siz);
493       mp = (union mhead *)((char *)mp + siz);
494     }
495   busy[nbuck] = 1;
496   CHAIN (mp) = nextf[nbuck];
497   nextf[nbuck] = nh;
498   busy[nbuck] = 0;
499 }
500
501 static void
502 block_signals (setp, osetp)
503      sigset_t *setp, *osetp;
504 {
505 #ifdef HAVE_POSIX_SIGNALS
506   sigfillset (setp);
507   sigemptyset (osetp);
508   sigprocmask (SIG_BLOCK, setp, osetp);
509 #else
510 #  if defined (HAVE_BSD_SIGNALS)
511   *osetp = sigsetmask (-1);
512 #  endif
513 #endif
514 }
515
516 static void
517 unblock_signals (setp, osetp)
518      sigset_t *setp, *osetp;
519 {
520 #ifdef HAVE_POSIX_SIGNALS
521   sigprocmask (SIG_SETMASK, osetp, (sigset_t *)NULL);
522 #else
523 #  if defined (HAVE_BSD_SIGNALS)
524   sigsetmask (*osetp);
525 #  endif
526 #endif
527 }
528
529 /* Return some memory to the system by reducing the break.  This is only
530    called with NU > pagebucket, so we're always assured of giving back
531    more than one page of memory. */  
532 static void
533 lesscore (nu)                   /* give system back some memory */
534      register int nu;           /* size index we're discarding  */
535 {
536   long siz;
537
538   siz = binsize (nu);
539   /* Should check for errors here, I guess. */
540   sbrk (-siz);
541   memtop -= siz;
542
543 #ifdef MALLOC_STATS
544   _mstats.nsbrk++;
545   _mstats.tsbrk -= siz;
546   _mstats.nlesscore[nu]++;
547 #endif
548 }
549
550 /* Ask system for more memory; add to NEXTF[NU].  BUSY[NU] must be set to 1. */  
551 static void
552 morecore (nu)
553      register int nu;           /* size index to get more of  */
554 {
555   register union mhead *mp;
556   register int nblks;
557   register long siz;
558   long sbrk_amt;                /* amount to get via sbrk() */
559   sigset_t set, oset;
560   int blocked_sigs;
561
562   /* Block all signals in case we are executed from a signal handler. */
563   blocked_sigs = 0;
564 #ifdef SHELL
565   if (interrupt_immediately || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
566 #endif
567     {
568       block_signals (&set, &oset);
569       blocked_sigs = 1;
570     }
571
572   siz = binsize (nu);   /* size of desired block for nextf[nu] */
573
574   if (siz < 0)
575     goto morecore_done;         /* oops */
576
577 #ifdef MALLOC_STATS
578   _mstats.nmorecore[nu]++;
579 #endif
580
581   /* Try to split a larger block here, if we're within the range of sizes
582      to split. */
583   if (nu >= SPLIT_MIN)
584     {
585       bsplit (nu);
586       if (nextf[nu] != 0)
587         goto morecore_done;
588     }
589
590   /* Try to coalesce two adjacent blocks from the free list on nextf[nu - 1],
591      if we can, and we're within the range of the block coalescing limits. */
592   if (nu >= COMBINE_MIN && nu < COMBINE_MAX && busy[nu - 1] == 0 && nextf[nu - 1])
593     {
594       bcoalesce (nu);
595       if (nextf[nu] != 0)
596         goto morecore_done;
597     }
598
599   /* Take at least a page, and figure out how many blocks of the requested
600      size we're getting. */
601   if (siz <= pagesz)
602     {
603       sbrk_amt = pagesz;
604       nblks = sbrk_amt / siz;
605     }
606   else
607     {
608       /* We always want to request an integral multiple of the page size
609          from the kernel, so let's compute whether or not `siz' is such
610          an amount.  If it is, we can just request it.  If not, we want
611          the smallest integral multiple of pagesize that is larger than
612          `siz' and will satisfy the request. */
613       sbrk_amt = siz & (pagesz - 1);
614       if (sbrk_amt == 0)
615         sbrk_amt = siz;
616       else
617         sbrk_amt = siz + pagesz - sbrk_amt;
618       nblks = 1;
619     }
620
621 #ifdef MALLOC_STATS
622   _mstats.nsbrk++;
623   _mstats.tsbrk += sbrk_amt;
624 #endif
625
626   mp = (union mhead *) sbrk (sbrk_amt);
627
628   /* Totally out of memory. */
629   if ((long)mp == -1)
630     goto morecore_done;
631
632   memtop += sbrk_amt;
633
634   /* shouldn't happen, but just in case -- require 8-byte alignment */
635   if ((long)mp & MALIGN_MASK)
636     {
637       mp = (union mhead *) (((long)mp + MALIGN_MASK) & ~MALIGN_MASK);
638       nblks--;
639     }
640
641   /* save new header and link the nblks blocks together */
642   nextf[nu] = mp;
643   while (1)
644     {
645       mp->mh_alloc = ISFREE;
646       mp->mh_index = nu;
647       if (--nblks <= 0) break;
648       CHAIN (mp) = (union mhead *)((char *)mp + siz);
649       mp = (union mhead *)((char *)mp + siz);
650     }
651   CHAIN (mp) = 0;
652
653 morecore_done:
654   if (blocked_sigs)
655     unblock_signals (&set, &oset);
656 }
657
658 static void
659 malloc_debug_dummy ()
660 {
661   write (1, "malloc_debug_dummy\n", 19);
662 }
663
664 #define PREPOP_BIN      2
665 #define PREPOP_SIZE     32
666
667 static int
668 pagealign ()
669 {
670   register int nunits;
671   register union mhead *mp;
672   long sbrk_needed;
673   char *curbrk;
674
675   pagesz = getpagesize ();
676   if (pagesz < 1024)
677     pagesz = 1024;
678
679   /* OK, how much do we need to allocate to make things page-aligned?
680      Some of this partial page will be wasted space, but we'll use as
681      much as we can.  Once we figure out how much to advance the break
682      pointer, go ahead and do it. */
683   memtop = curbrk = sbrk (0);
684   sbrk_needed = pagesz - ((long)curbrk & (pagesz - 1)); /* sbrk(0) % pagesz */
685   if (sbrk_needed < 0)
686     sbrk_needed += pagesz;
687
688   /* Now allocate the wasted space. */
689   if (sbrk_needed)
690     {
691 #ifdef MALLOC_STATS
692       _mstats.nsbrk++;
693       _mstats.tsbrk += sbrk_needed;
694 #endif
695       curbrk = sbrk (sbrk_needed);
696       if ((long)curbrk == -1)
697         return -1;
698       memtop += sbrk_needed;
699
700       /* Take the memory which would otherwise be wasted and populate the most
701          popular bin (2 == 32 bytes) with it.  Add whatever we need to curbrk
702          to make things 32-byte aligned, compute how many 32-byte chunks we're
703          going to get, and set up the bin. */
704       curbrk += sbrk_needed & (PREPOP_SIZE - 1);
705       sbrk_needed -= sbrk_needed & (PREPOP_SIZE - 1);
706       nunits = sbrk_needed / PREPOP_SIZE;
707
708       if (nunits > 0)
709         {
710           mp = (union mhead *)curbrk;
711
712           nextf[PREPOP_BIN] = mp;
713           while (1)
714             {
715               mp->mh_alloc = ISFREE;
716               mp->mh_index = PREPOP_BIN;
717               if (--nunits <= 0) break;
718               CHAIN(mp) = (union mhead *)((char *)mp + PREPOP_SIZE);
719               mp = (union mhead *)((char *)mp + PREPOP_SIZE);
720             }
721           CHAIN(mp) = 0;
722         }
723     }
724
725   /* compute which bin corresponds to the page size. */
726   for (nunits = 7; nunits < NBUCKETS; nunits++)
727     if (pagesz <= binsize(nunits))
728       break;
729   pagebucket = nunits;
730
731   return 0;
732 }
733     
734 static PTR_T
735 internal_malloc (n, file, line, flags)          /* get a block */
736      size_t n;
737      const char *file;
738      int line, flags;
739 {
740   register union mhead *p;
741   register int nunits;
742   register char *m, *z;
743   long nbytes;
744   mguard_t mg;
745
746   /* Get the system page size and align break pointer so future sbrks will
747      be page-aligned.  The page size must be at least 1K -- anything
748      smaller is increased. */
749   if (pagesz == 0)
750     if (pagealign () < 0)
751       return ((PTR_T)NULL);
752  
753   /* Figure out how many bytes are required, rounding up to the nearest
754      multiple of 8, then figure out which nextf[] area to use.  Try to
755      be smart about where to start searching -- if the number of bytes
756      needed is greater than the page size, we can start at pagebucket. */
757   nbytes = ALLOCATED_BYTES(n);
758   nunits = (nbytes <= (pagesz >> 1)) ? STARTBUCK : pagebucket;
759   for ( ; nunits < NBUCKETS; nunits++)
760     if (nbytes <= binsize(nunits))
761       break;
762
763   /* Silently reject too-large requests. */
764   if (nunits >= NBUCKETS)
765     return ((PTR_T) NULL);
766
767   /* In case this is reentrant use of malloc from signal handler,
768      pick a block size that no other malloc level is currently
769      trying to allocate.  That's the easiest harmless way not to
770      interfere with the other level of execution.  */
771 #ifdef MALLOC_STATS
772   if (busy[nunits]) _mstats.nrecurse++;
773 #endif
774   while (busy[nunits]) nunits++;
775   busy[nunits] = 1;
776
777   if (nunits > maxbuck)
778     maxbuck = nunits;
779
780   /* If there are no blocks of the appropriate size, go get some */
781   if (nextf[nunits] == 0)
782     morecore (nunits);
783
784   /* Get one block off the list, and set the new list head */
785   if ((p = nextf[nunits]) == NULL)
786     {
787       busy[nunits] = 0;
788       return NULL;
789     }
790   nextf[nunits] = CHAIN (p);
791   busy[nunits] = 0;
792
793   /* Check for free block clobbered */
794   /* If not for this check, we would gobble a clobbered free chain ptr
795      and bomb out on the NEXT allocate of this size block */
796   if (p->mh_alloc != ISFREE || p->mh_index != nunits)
797     xbotch ((PTR_T)(p+1), 0, _("malloc: block on free list clobbered"), file, line);
798
799   /* Fill in the info, and set up the magic numbers for range checking. */
800   p->mh_alloc = ISALLOC;
801   p->mh_magic2 = MAGIC2;
802   p->mh_nbytes = n;
803
804   /* End guard */
805   mg.i = n;
806   z = mg.s;
807   m = (char *) (p + 1) + n;
808   *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++;
809
810 #ifdef MEMSCRAMBLE
811   if (n)
812     MALLOC_MEMSET ((char *)(p + 1), 0xdf, n);   /* scramble previous contents */
813 #endif
814 #ifdef MALLOC_STATS
815   _mstats.nmalloc[nunits]++;
816   _mstats.tmalloc[nunits]++;
817   _mstats.nmal++;
818   _mstats.bytesreq += n;
819 #endif /* MALLOC_STATS */
820
821 #ifdef MALLOC_TRACE
822   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
823     mtrace_alloc ("malloc", p + 1, n, file, line);
824   else if (_malloc_trace_buckets[nunits])
825     mtrace_alloc ("malloc", p + 1, n, file, line);
826 #endif
827
828 #ifdef MALLOC_REGISTER
829   if (malloc_register && (flags & MALLOC_NOREG) == 0)
830     mregister_alloc ("malloc", p + 1, n, file, line);
831 #endif
832
833 #ifdef MALLOC_WATCH
834   if (_malloc_nwatch > 0)
835     _malloc_ckwatch (p + 1, file, line, W_ALLOC, n);
836 #endif
837
838   return (PTR_T) (p + 1);
839 }
840
841 static void
842 internal_free (mem, file, line, flags)
843      PTR_T mem;
844      const char *file;
845      int line, flags;
846 {
847   register union mhead *p;
848   register char *ap, *z;
849   register int nunits;
850   register unsigned int nbytes;
851   int ubytes;           /* caller-requested size */
852   mguard_t mg;
853
854   if ((ap = (char *)mem) == 0)
855     return;
856
857   p = (union mhead *) ap - 1;
858
859   if (p->mh_alloc == ISMEMALIGN)
860     {
861       ap -= p->mh_nbytes;
862       p = (union mhead *) ap - 1;
863     }
864
865 #if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER)
866   if (malloc_trace || malloc_register)
867     ubytes = p->mh_nbytes;
868 #endif
869
870   if (p->mh_alloc != ISALLOC)
871     {
872       if (p->mh_alloc == ISFREE)
873         xbotch (mem, ERR_DUPFREE,
874                 _("free: called with already freed block argument"), file, line);
875       else
876         xbotch (mem, ERR_UNALLOC,
877                 _("free: called with unallocated block argument"), file, line);
878     }
879
880   ASSERT (p->mh_magic2 == MAGIC2);
881
882   nunits = p->mh_index;
883   nbytes = ALLOCATED_BYTES(p->mh_nbytes);
884   /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
885      are now used for the number of bytes allocated, a simple check of
886      mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
887      We sanity-check the value of mh_nbytes against the size of the blocks
888      in the appropriate bucket before we use it.  This can still cause problems
889      and obscure errors if mh_nbytes is wrong but still within range; the
890      checks against the size recorded at the end of the chunk will probably
891      fail then.  Using MALLOC_REGISTER will help here, since it saves the
892      original number of bytes requested. */
893
894   if (IN_BUCKET(nbytes, nunits) == 0)
895     xbotch (mem, ERR_UNDERFLOW,
896             _("free: underflow detected; mh_nbytes out of range"), file, line);
897
898   ap += p->mh_nbytes;
899   z = mg.s;
900   *z++ = *ap++, *z++ = *ap++, *z++ = *ap++, *z++ = *ap++;  
901   if (mg.i != p->mh_nbytes)
902     xbotch (mem, ERR_ASSERT_FAILED, _("free: start and end chunk sizes differ"), file, line);
903
904 #if 1
905   if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == memtop))
906 #else
907   if (((char *)p + binsize(nunits) == memtop) && nunits >= LESSCORE_MIN)
908 #endif
909     {
910       /* If above LESSCORE_FRC, give back unconditionally.  This should be set
911          high enough to be infrequently encountered.  If between LESSCORE_MIN
912          and LESSCORE_FRC, call lesscore if the bucket is marked as busy or if
913          there's already a block on the free list. */
914       if ((nunits >= LESSCORE_FRC) || busy[nunits] || nextf[nunits] != 0)
915         {
916           lesscore (nunits);
917           /* keeps the tracing and registering code in one place */
918           goto free_return;
919         }
920     }
921
922 #ifdef MEMSCRAMBLE
923   if (p->mh_nbytes)
924     MALLOC_MEMSET (mem, 0xcf, p->mh_nbytes);
925 #endif
926
927   ASSERT (nunits < NBUCKETS);
928
929   if (busy[nunits] == 1)
930     {
931       xsplit (p, nunits);       /* split block and add to different chain */
932       goto free_return;
933     }
934
935   p->mh_alloc = ISFREE;
936   /* Protect against signal handlers calling malloc.  */
937   busy[nunits] = 1;
938   /* Put this block on the free list.  */
939   CHAIN (p) = nextf[nunits];
940   nextf[nunits] = p;
941   busy[nunits] = 0;
942
943 free_return:
944   ;             /* Empty statement in case this is the end of the function */
945
946 #ifdef MALLOC_STATS
947   _mstats.nmalloc[nunits]--;
948   _mstats.nfre++;
949 #endif /* MALLOC_STATS */
950
951 #ifdef MALLOC_TRACE
952   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
953     mtrace_free (mem, ubytes, file, line);
954   else if (_malloc_trace_buckets[nunits])
955     mtrace_free (mem, ubytes, file, line);
956 #endif
957
958 #ifdef MALLOC_REGISTER
959   if (malloc_register && (flags & MALLOC_NOREG) == 0)
960     mregister_free (mem, ubytes, file, line);
961 #endif
962
963 #ifdef MALLOC_WATCH
964   if (_malloc_nwatch > 0)
965     _malloc_ckwatch (mem, file, line, W_FREE, ubytes);
966 #endif
967 }
968
969 static PTR_T
970 internal_realloc (mem, n, file, line, flags)
971      PTR_T mem;
972      register size_t n;
973      const char *file;
974      int line, flags;
975 {
976   register union mhead *p;
977   register u_bits32_t tocopy;
978   register unsigned int nbytes;
979   register int nunits;
980   register char *m, *z;
981   mguard_t mg;
982
983 #ifdef MALLOC_STATS
984   _mstats.nrealloc++;
985 #endif
986
987   if (n == 0)
988     {
989       internal_free (mem, file, line, MALLOC_INTERNAL);
990       return (NULL);
991     }
992   if ((p = (union mhead *) mem) == 0)
993     return internal_malloc (n, file, line, MALLOC_INTERNAL);
994
995   p--;
996   nunits = p->mh_index;
997   ASSERT (nunits < NBUCKETS);
998
999   if (p->mh_alloc != ISALLOC)
1000     xbotch (mem, ERR_UNALLOC,
1001             _("realloc: called with unallocated block argument"), file, line);
1002
1003   ASSERT (p->mh_magic2 == MAGIC2);
1004   nbytes = ALLOCATED_BYTES(p->mh_nbytes);
1005   /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
1006      are now used for the number of bytes allocated, a simple check of
1007      mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
1008      We sanity-check the value of mh_nbytes against the size of the blocks
1009      in the appropriate bucket before we use it.  This can still cause problems
1010      and obscure errors if mh_nbytes is wrong but still within range; the
1011      checks against the size recorded at the end of the chunk will probably
1012      fail then.  Using MALLOC_REGISTER will help here, since it saves the
1013      original number of bytes requested. */
1014   if (IN_BUCKET(nbytes, nunits) == 0)
1015     xbotch (mem, ERR_UNDERFLOW,
1016             _("realloc: underflow detected; mh_nbytes out of range"), file, line);
1017
1018   m = (char *)mem + (tocopy = p->mh_nbytes);
1019   z = mg.s;
1020   *z++ = *m++, *z++ = *m++, *z++ = *m++, *z++ = *m++;
1021   if (mg.i != p->mh_nbytes)
1022     xbotch (mem, ERR_ASSERT_FAILED, _("realloc: start and end chunk sizes differ"), file, line);
1023
1024 #ifdef MALLOC_WATCH
1025   if (_malloc_nwatch > 0)
1026     _malloc_ckwatch (p + 1, file, line, W_REALLOC, n);
1027 #endif
1028 #ifdef MALLOC_STATS
1029   _mstats.bytesreq += (n < tocopy) ? 0 : n - tocopy;
1030 #endif
1031
1032   /* See if desired size rounds to same power of 2 as actual size. */
1033   nbytes = ALLOCATED_BYTES(n);
1034
1035   /* If ok, use the same block, just marking its size as changed.  */
1036   if (RIGHT_BUCKET(nbytes, nunits))
1037     {
1038 #if 0
1039       m = (char *)mem + p->mh_nbytes;
1040 #else
1041       /* Compensate for increment above. */
1042       m -= 4;
1043 #endif
1044       *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;
1045       m = (char *)mem + (p->mh_nbytes = n);
1046
1047       mg.i = n;
1048       z = mg.s;
1049       *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++;      
1050
1051       return mem;
1052     }
1053
1054   if (n < tocopy)
1055     tocopy = n;
1056
1057 #ifdef MALLOC_STATS
1058   _mstats.nrcopy++;
1059 #endif
1060
1061   if ((m = internal_malloc (n, file, line, MALLOC_INTERNAL|MALLOC_NOTRACE|MALLOC_NOREG)) == 0)
1062     return 0;
1063   FASTCOPY (mem, m, tocopy);
1064   internal_free (mem, file, line, MALLOC_INTERNAL);
1065
1066 #ifdef MALLOC_TRACE
1067   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
1068     mtrace_alloc ("realloc", m, n, file, line);
1069   else if (_malloc_trace_buckets[nunits])
1070     mtrace_alloc ("realloc", m, n, file, line);
1071 #endif
1072
1073 #ifdef MALLOC_REGISTER
1074   if (malloc_register && (flags & MALLOC_NOREG) == 0)
1075     mregister_alloc ("realloc", m, n, file, line);
1076 #endif
1077
1078 #ifdef MALLOC_WATCH
1079   if (_malloc_nwatch > 0)
1080     _malloc_ckwatch (m, file, line, W_RESIZED, n);
1081 #endif
1082
1083   return m;
1084 }
1085
1086 static PTR_T
1087 internal_memalign (alignment, size, file, line, flags)
1088      size_t alignment;
1089      size_t size;
1090      const char *file;
1091      int line, flags;
1092 {
1093   register char *ptr;
1094   register char *aligned;
1095   register union mhead *p;
1096
1097   ptr = internal_malloc (size + alignment, file, line, MALLOC_INTERNAL);
1098
1099   if (ptr == 0)
1100     return 0;
1101   /* If entire block has the desired alignment, just accept it.  */
1102   if (((long) ptr & (alignment - 1)) == 0)
1103     return ptr;
1104   /* Otherwise, get address of byte in the block that has that alignment.  */
1105 #if 0
1106   aligned = (char *) (((long) ptr + alignment - 1) & -alignment);
1107 #else
1108   aligned = (char *) (((long) ptr + alignment - 1) & (~alignment + 1));
1109 #endif
1110
1111   /* Store a suitable indication of how to free the block,
1112      so that free can find the true beginning of it.  */
1113   p = (union mhead *) aligned - 1;
1114   p->mh_nbytes = aligned - ptr;
1115   p->mh_alloc = ISMEMALIGN;
1116
1117   return aligned;
1118 }
1119
1120 #if !defined (NO_VALLOC)
1121 /* This runs into trouble with getpagesize on HPUX, and Multimax machines.
1122    Patching out seems cleaner than the ugly fix needed.  */
1123 static PTR_T
1124 internal_valloc (size, file, line, flags)
1125      size_t size;
1126      const char *file;
1127      int line, flags;
1128 {
1129   return internal_memalign (getpagesize (), size, file, line, flags|MALLOC_INTERNAL);
1130 }
1131 #endif /* !NO_VALLOC */
1132
1133 #ifndef NO_CALLOC
1134 static PTR_T
1135 internal_calloc (n, s, file, line, flags)
1136      size_t n, s;
1137      const char *file;
1138      int line, flags;
1139 {
1140   size_t total;
1141   PTR_T result;
1142
1143   total = n * s;
1144   result = internal_malloc (total, file, line, flags|MALLOC_INTERNAL);
1145   if (result)
1146     memset (result, 0, total);
1147   return result;  
1148 }
1149
1150 static void
1151 internal_cfree (p, file, line, flags)
1152      PTR_T p;
1153      const char *file;
1154      int line, flags;
1155 {
1156   internal_free (p, file, line, flags|MALLOC_INTERNAL);
1157 }
1158 #endif /* !NO_CALLOC */
1159
1160 #ifdef MALLOC_STATS
1161 int
1162 malloc_free_blocks (size)
1163      int size;
1164 {
1165   int nfree;
1166   register union mhead *p;
1167
1168   nfree = 0;
1169   for (p = nextf[size]; p; p = CHAIN (p))
1170     nfree++;
1171
1172   return nfree;
1173 }
1174 #endif
1175
1176 #if defined (MALLOC_WRAPFUNCS)
1177 PTR_T
1178 sh_malloc (bytes, file, line)
1179      size_t bytes;
1180      const char *file;
1181      int line;
1182 {
1183   return internal_malloc (bytes, file, line, MALLOC_WRAPPER);
1184 }
1185
1186 PTR_T
1187 sh_realloc (ptr, size, file, line)
1188      PTR_T ptr;
1189      size_t size;
1190      const char *file;
1191      int line;
1192 {
1193   return internal_realloc (ptr, size, file, line, MALLOC_WRAPPER);
1194 }
1195
1196 void
1197 sh_free (mem, file, line)
1198      PTR_T mem;
1199      const char *file;
1200      int line;
1201 {
1202   internal_free (mem, file, line, MALLOC_WRAPPER);
1203 }
1204
1205 PTR_T
1206 sh_memalign (alignment, size, file, line)
1207      size_t alignment;
1208      size_t size;
1209      const char *file;
1210      int line;
1211 {
1212   return internal_memalign (alignment, size, file, line, MALLOC_WRAPPER);
1213 }
1214
1215 #ifndef NO_CALLOC
1216 PTR_T
1217 sh_calloc (n, s, file, line)
1218      size_t n, s;
1219      const char *file;
1220      int line;
1221 {
1222   return internal_calloc (n, s, file, line, MALLOC_WRAPPER);
1223 }
1224
1225 void
1226 sh_cfree (mem, file, line)
1227      PTR_T mem;
1228      const char *file;
1229      int line;
1230 {
1231   internal_cfree (mem, file, line, MALLOC_WRAPPER);
1232 }
1233 #endif
1234
1235 #ifndef NO_VALLOC
1236 PTR_T
1237 sh_valloc (size, file, line)
1238      size_t size;
1239      const char *file;
1240      int line;
1241 {
1242   return internal_valloc (size, file, line, MALLOC_WRAPPER);
1243 }
1244 #endif /* !NO_VALLOC */
1245
1246 #endif /* MALLOC_WRAPFUNCS */
1247
1248 /* Externally-available functions that call their internal counterparts. */
1249
1250 PTR_T
1251 malloc (size)
1252      size_t size;
1253 {
1254   return internal_malloc (size, (char *)NULL, 0, 0);
1255 }
1256
1257 PTR_T
1258 realloc (mem, nbytes)
1259      PTR_T mem;
1260      size_t nbytes;
1261 {
1262   return internal_realloc (mem, nbytes, (char *)NULL, 0, 0);
1263 }
1264
1265 void
1266 free (mem)
1267      PTR_T mem;
1268 {
1269   internal_free (mem,  (char *)NULL, 0, 0);
1270 }
1271
1272 PTR_T
1273 memalign (alignment, size)
1274      size_t alignment;
1275      size_t size;
1276 {
1277   return internal_memalign (alignment, size, (char *)NULL, 0, 0);
1278 }
1279
1280 #ifndef NO_VALLOC
1281 PTR_T
1282 valloc (size)
1283      size_t size;
1284 {
1285   return internal_valloc (size, (char *)NULL, 0, 0);
1286 }
1287 #endif
1288
1289 #ifndef NO_CALLOC
1290 PTR_T
1291 calloc (n, s)
1292      size_t n, s;
1293 {
1294   return internal_calloc (n, s, (char *)NULL, 0, 0);
1295 }
1296
1297 void
1298 cfree (mem)
1299      PTR_T mem;
1300 {
1301   internal_cfree (mem, (char *)NULL, 0, 0);
1302 }
1303 #endif