Imported from ../bash-2.01.tar.gz.
[platform/upstream/bash.git] / lib / malloc / malloc.c
1 /* dynamic memory allocation for GNU. */
2
3 /*  Copyright (C) 1985, 1987 Free Software Foundation, Inc.
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 1, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them.   Help stamp out software-hoarding!  */
22
23 /*
24  * @(#)nmalloc.c 1 (Caltech) 2/21/82
25  *
26  *      U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
27  *
28  *      Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
29  *
30  * This is a very fast storage allocator.  It allocates blocks of a small 
31  * number of different sizes, and keeps free lists of each size.  Blocks
32  * that don't exactly fit are passed up to the next larger size.  In this 
33  * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
34  * This is designed for use in a program that uses vast quantities of
35  * memory, but bombs when it runs out.  To make it a little better, it
36  * warns the user when he starts to get near the end.
37  *
38  * June 84, ACT: modified rcheck code to check the range given to malloc,
39  * rather than the range determined by the 2-power used.
40  *
41  * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
42  * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
43  * You should call malloc_init to reinitialize after loading dumped Emacs.
44  * Call malloc_stats to get info on memory stats if MSTATS turned on.
45  * realloc knows how to return same block given, just changing its size,
46  * if the power of 2 is correct.
47  */
48
49 /*
50  * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
51  * smallest allocatable block is 8 bytes.  The overhead information will
52  * go in the first int of the block, and the returned pointer will point
53  * to the second.
54  *
55 #ifdef MSTATS
56  * nmalloc[i] is the difference between the number of mallocs and frees
57  * for a given block size.
58 #endif
59  */
60
61 /* Define this to have free() write 0xcf into memory as it's freed, to
62    uncover callers that refer to freed memory. */
63 /* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE */
64 #if !defined (NO_MEMSCRAMBLE)
65 #  define MEMSCRAMBLE
66 #endif
67
68 #if defined (emacs) || defined (HAVE_CONFIG_H)
69 #  include <config.h>
70 #endif /* emacs */
71
72 #if defined (HAVE_UNISTD_H)
73 #  include <unistd.h>
74 #endif
75
76 /* Determine which kind of system this is.  */
77 #if defined (SHELL)
78 #  include "bashtypes.h"
79 #else
80 #  include <sys/types.h>
81 #endif
82 #include <signal.h>
83
84 /* Define getpagesize () if the system does not.  */
85 #ifndef HAVE_GETPAGESIZE
86 #  include "getpagesize.h"
87 #endif
88
89 #if defined (HAVE_RESOURCE)
90 #  include <sys/time.h>
91 #  include <sys/resource.h>
92 #endif /* HAVE_RESOURCE */
93
94 /* Check for the needed symbols.  If they aren't present, this
95    system's <sys/resource.h> isn't very useful to us. */
96 #if !defined (RLIMIT_DATA)
97 #  undef HAVE_RESOURCE
98 #endif
99
100 #if __GNUC__ > 1
101 #  define FASTCOPY(s, d, n)  __builtin_memcpy (d, s, n)
102 #else /* !__GNUC__ */
103 #  if !defined (HAVE_BCOPY)
104 #    if !defined (HAVE_MEMMOVE)
105 #      define FASTCOPY(s, d, n)  memcpy (d, s, n)
106 #    else
107 #      define FASTCOPY(s, d, n)  memmove (d, s, n)
108 #    endif /* !HAVE_MEMMOVE */
109 #  else /* HAVE_BCOPY */
110 #    define FASTCOPY(s, d, n)  bcopy (s, d, n)
111 #  endif /* HAVE_BCOPY */
112 #endif /* !__GNUC__ */
113
114 #if !defined (NULL)
115 #  define NULL 0
116 #endif
117
118 #define start_of_data() &etext
119
120 #define ISALLOC ((char) 0xf7)   /* magic byte that implies allocation */
121 #define ISFREE ((char) 0x54)    /* magic byte that implies free block */
122                                 /* this is for error checking only */
123 #define ISMEMALIGN ((char) 0xd6)  /* Stored before the value returned by
124                                      memalign, with the rest of the word
125                                      being the distance to the true
126                                      beginning of the block.  */
127 extern char etext;
128
129 #if !defined (SBRK_DECLARED)
130 extern char *sbrk ();
131 #endif /* !SBRK_DECLARED */
132
133 /* These two are for user programs to look at, when they are interested.  */
134 unsigned int malloc_sbrk_used;       /* amount of data space used now */
135 unsigned int malloc_sbrk_unused;     /* amount more we can have */
136
137 /* start of data space; can be changed by calling init_malloc */
138 static char *data_space_start;
139
140 static void get_lim_data ();
141
142 #ifdef MSTATS
143 static int nmalloc[30];
144 static int nmal, nfre;
145 #endif /* MSTATS */
146
147 /* If range checking is not turned on, all we have is a flag indicating
148    whether memory is allocated, an index in nextf[], and a size field; to
149    realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
150    on whether the former can hold the exact size (given the value of
151    'index').  If range checking is on, we always need to know how much space
152    is allocated, so the 'size' field is never used. */
153
154 struct mhead {
155         char     mh_alloc;      /* ISALLOC or ISFREE */
156         char     mh_index;      /* index in nextf[] */
157 /* Remainder are valid only when block is allocated */
158         unsigned short mh_size; /* size, if < 0x10000 */
159 #ifdef RCHECK
160         unsigned int mh_nbytes; /* number of bytes allocated */
161         int      mh_magic4;     /* should be == MAGIC4 */
162 #endif /* RCHECK */
163 };
164
165 /* Access free-list pointer of a block.
166   It is stored at block + 4.
167   This is not a field in the mhead structure
168   because we want sizeof (struct mhead)
169   to describe the overhead for when the block is in use,
170   and we do not want the free-list pointer to count in that.  */
171
172 #define CHAIN(a) \
173   (*(struct mhead **) (sizeof (char *) + (char *) (a)))
174
175 #ifdef RCHECK
176 #  include <stdio.h>
177 #  if !defined (botch)
178 #    define botch(x) abort ()
179 #  else
180 extern void botch();
181 #  endif /* botch */
182
183 #  if !defined (__STRING)
184 #    if defined (__STDC__)
185 #      define __STRING(x) #x
186 #    else
187 #      define __STRING(x) "x"
188 #    endif
189 #  endif
190
191   /* To implement range checking, we write magic values in at the beginning
192      and end of each allocated block, and make sure they are undisturbed
193      whenever a free or a realloc occurs. */
194
195   /* Written in each of the 4 bytes following the block's real space */
196 #  define MAGIC1 0x55
197   /* Written in the 4 bytes before the block's real space */
198 #  define MAGIC4 0x55555555
199 #  define ASSERT(p) if (!(p)) botch(__STRING(p)); else
200 #  define EXTRA  4              /* 4 bytes extra for MAGIC1s */
201 #else /* !RCHECK */
202 #  define ASSERT(p)
203 #  define EXTRA  0
204 #endif /* RCHECK */
205
206 /* nextf[i] is free list of blocks of size 2**(i + 3)  */
207
208 static struct mhead *nextf[30];
209
210 /* busy[i] is nonzero while allocation of block size i is in progress.  */
211
212 static char busy[30];
213
214 /* Number of bytes of writable memory we can expect to be able to get */
215 static unsigned int lim_data;
216
217 /* Level number of warnings already issued.
218   0 -- no warnings issued.
219   1 -- 75% warning already issued.
220   2 -- 85% warning already issued.
221 */
222 static int warnlevel;
223
224 /* Function to call to issue a warning;
225    0 means don't issue them.  */
226 static void (*warnfunction) ();
227
228 /* nonzero once initial bunch of free blocks made */
229 static int gotpool;
230
231 char *_malloc_base;
232
233 static void getpool ();
234
235 /* Cause reinitialization based on job parameters;
236   also declare where the end of pure storage is. */
237 void
238 malloc_init (start, warnfun)
239      char *start;
240      void (*warnfun) ();
241 {
242   if (start)
243     data_space_start = start;
244   lim_data = 0;
245   warnlevel = 0;
246   warnfunction = warnfun;
247 }
248
249 /* Return the maximum size to which MEM can be realloc'd
250    without actually requiring copying.  */
251
252 int
253 malloc_usable_size (mem)
254      char *mem;
255 {
256   int blocksize = 8 << (((struct mhead *) mem) - 1) -> mh_index;
257
258   return blocksize - sizeof (struct mhead) - EXTRA;
259 }
260
261 static void
262 morecore (nu)                   /* ask system for more memory */
263      register int nu;           /* size index to get more of  */
264 {
265   register char *cp;
266   register int nblks;
267   register unsigned int siz;
268
269   /* Block all signals in case we are executed from a signal handler. */
270 #if defined (HAVE_BSD_SIGNALS)
271   int oldmask;
272   oldmask = sigsetmask (-1);
273 #else
274 #  if defined (HAVE_POSIX_SIGNALS)
275   sigset_t set, oset;
276   sigfillset (&set);
277   sigemptyset (&oset);
278   sigprocmask (SIG_BLOCK, &set, &oset);
279 #  endif /* HAVE_POSIX_SIGNALS */
280 #endif /* HAVE_BSD_SIGNALS */
281
282   if (!data_space_start)
283     {
284       data_space_start = start_of_data ();
285     }
286
287   if (lim_data == 0)
288     get_lim_data ();
289
290  /* On initial startup, get two blocks of each size up to 1k bytes */
291   if (!gotpool)
292     { getpool (); getpool (); gotpool = 1; }
293
294   /* Find current end of memory and issue warning if getting near max */
295
296   cp = sbrk (0);
297   siz = cp - data_space_start;
298   malloc_sbrk_used = siz;
299   malloc_sbrk_unused = lim_data - siz;
300
301   if (warnfunction)
302     switch (warnlevel)
303       {
304       case 0: 
305         if (siz > (lim_data / 4) * 3)
306           {
307             warnlevel++;
308             (*warnfunction) ("Warning: past 75% of memory limit");
309           }
310         break;
311       case 1: 
312         if (siz > (lim_data / 20) * 17)
313           {
314             warnlevel++;
315             (*warnfunction) ("Warning: past 85% of memory limit");
316           }
317         break;
318       case 2: 
319         if (siz > (lim_data / 20) * 19)
320           {
321             warnlevel++;
322             (*warnfunction) ("Warning: past 95% of memory limit");
323           }
324         break;
325       }
326
327   if ((int) cp & 0x3ff) /* land on 1K boundaries */
328     sbrk (1024 - ((int) cp & 0x3ff));
329
330  /* Take at least 2k, and figure out how many blocks of the desired size
331     we're about to get */
332   nblks = 1;
333   if ((siz = nu) < 8)
334     nblks = 1 << ((siz = 8) - nu);
335
336   if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
337     return;                     /* no more room! */
338
339   if ((int) cp & 7)
340     {           /* shouldn't happen, but just in case */
341       cp = (char *) (((int) cp + 8) & ~7);
342       nblks--;
343     }
344
345  /* save new header and link the nblks blocks together */
346   nextf[nu] = (struct mhead *) cp;
347   siz = 1 << (nu + 3);
348   while (1)
349     {
350       ((struct mhead *) cp) -> mh_alloc = ISFREE;
351       ((struct mhead *) cp) -> mh_index = nu;
352       if (--nblks <= 0) break;
353       CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
354       cp += siz;
355     }
356   CHAIN ((struct mhead *) cp) = 0;
357
358 #if defined (HAVE_BSD_SIGNALS)
359   sigsetmask (oldmask);
360 #else
361 #  if defined (HAVE_POSIX_SIGNALS)
362   sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
363 #  endif
364 #endif /* HAVE_BSD_SIGNALS */
365 }
366
367 static void
368 getpool ()
369 {
370   register int nu;
371   register char *cp = sbrk (0);
372
373   if ((int) cp & 0x3ff) /* land on 1K boundaries */
374     sbrk (1024 - ((int) cp & 0x3ff));
375
376   /* Record address of start of space allocated by malloc.  */
377   if (_malloc_base == 0)
378     _malloc_base = cp;
379
380   /* Get 2k of storage */
381
382   cp = sbrk (04000);
383   if (cp == (char *) -1)
384     return;
385
386   /* Divide it into an initial 8-word block
387      plus one block of size 2**nu for nu = 3 ... 10.  */
388
389   CHAIN (cp) = nextf[0];
390   nextf[0] = (struct mhead *) cp;
391   ((struct mhead *) cp) -> mh_alloc = ISFREE;
392   ((struct mhead *) cp) -> mh_index = 0;
393   cp += 8;
394
395   for (nu = 0; nu < 7; nu++)
396     {
397       CHAIN (cp) = nextf[nu];
398       nextf[nu] = (struct mhead *) cp;
399       ((struct mhead *) cp) -> mh_alloc = ISFREE;
400       ((struct mhead *) cp) -> mh_index = nu;
401       cp += 8 << nu;
402     }
403 }
404
405 #if defined (MEMSCRAMBLE) || !defined (NO_CALLOC)
406 static char *
407 zmemset (s, c, n)
408      char *s;
409      int c;
410      register int n;
411 {
412   register char *sp;
413
414   sp = s;
415   while (--n >= 0)
416     *sp++ = c;
417   return (s);
418 }
419 #endif /* MEMSCRAMBLE || !NO_CALLOC */
420
421 char *
422 malloc (n)              /* get a block */
423      unsigned int n;
424 {
425   register struct mhead *p;
426   register unsigned int nbytes;
427   register int nunits = 0;
428
429   /* Figure out how many bytes are required, rounding up to the nearest
430      multiple of 4, then figure out which nextf[] area to use */
431   nbytes = (n + sizeof *p + EXTRA + 3) & ~3;
432   {
433     register unsigned int   shiftr = (nbytes - 1) >> 2;
434
435     while (shiftr >>= 1)
436       nunits++;
437   }
438
439   /* In case this is reentrant use of malloc from signal handler,
440      pick a block size that no other malloc level is currently
441      trying to allocate.  That's the easiest harmless way not to
442      interfere with the other level of execution.  */
443   while (busy[nunits]) nunits++;
444   busy[nunits] = 1;
445
446   /* If there are no blocks of the appropriate size, go get some */
447   /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
448   if (nextf[nunits] == 0)
449     morecore (nunits);
450
451   /* Get one block off the list, and set the new list head */
452   if ((p = nextf[nunits]) == 0)
453     {
454       busy[nunits] = 0;
455       return 0;
456     }
457   nextf[nunits] = CHAIN (p);
458   busy[nunits] = 0;
459
460   /* Check for free block clobbered */
461   /* If not for this check, we would gobble a clobbered free chain ptr */
462   /* and bomb out on the NEXT allocate of this size block */
463   if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
464 #ifdef RCHECK
465     botch ("block on free list clobbered");
466 #else /* not RCHECK */
467     abort ();
468 #endif /* not RCHECK */
469
470   /* Fill in the info, and if range checking, set up the magic numbers */
471   p -> mh_alloc = ISALLOC;
472 #ifdef RCHECK
473   p -> mh_nbytes = n;
474   p -> mh_magic4 = MAGIC4;
475   {
476     register char  *m = (char *) (p + 1) + n;
477
478     *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
479   }
480 #else /* not RCHECK */
481   p -> mh_size = n;
482 #endif /* not RCHECK */
483 #ifdef MEMSCRAMBLE
484   zmemset ((char *)(p + 1), 0xdf, n);   /* scramble previous contents */
485 #endif
486 #ifdef MSTATS
487   nmalloc[nunits]++;
488   nmal++;
489 #endif /* MSTATS */
490   return (char *) (p + 1);
491 }
492
493 void
494 free (mem)
495      char *mem;
496 {
497   register struct mhead *p;
498   {
499     register char *ap = mem;
500
501     if (ap == 0)
502       return;
503
504     p = (struct mhead *) ap - 1;
505
506     if (p -> mh_alloc == ISMEMALIGN)
507       {
508 #ifdef RCHECK
509         ap -= p->mh_nbytes;
510 #else
511         ap -= p->mh_size;       /* XXX */
512 #endif
513         p = (struct mhead *) ap - 1;
514       }
515
516 #ifndef RCHECK
517     if (p -> mh_alloc != ISALLOC)
518       abort ();
519
520 #else /* RCHECK */
521     if (p -> mh_alloc != ISALLOC)
522       {
523         if (p -> mh_alloc == ISFREE)
524           botch ("free: Called with already freed block argument\n");
525         else
526           botch ("free: Called with unallocated block argument\n");
527       }
528
529     ASSERT (p -> mh_magic4 == MAGIC4);
530     ap += p -> mh_nbytes;
531     ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
532     ASSERT (*ap++ == MAGIC1); ASSERT (*ap   == MAGIC1);
533 #endif /* RCHECK */
534   }
535 #ifdef MEMSCRAMBLE
536   {
537     register int n;
538     
539 #ifdef RCHECK
540     n = p->mh_nbytes;
541 #else /* not RCHECK */
542     n = p->mh_size;
543 #endif /* not RCHECK */
544     zmemset (mem, 0xcf, n);
545   }
546 #endif
547   {
548     register int nunits = p -> mh_index;
549
550     ASSERT (nunits <= 29);
551     p -> mh_alloc = ISFREE;
552
553     /* Protect against signal handlers calling malloc.  */
554     busy[nunits] = 1;
555     /* Put this block on the free list.  */
556     CHAIN (p) = nextf[nunits];
557     nextf[nunits] = p;
558     busy[nunits] = 0;
559
560 #ifdef MSTATS
561     nmalloc[nunits]--;
562     nfre++;
563 #endif /* MSTATS */
564   }
565 }
566
567 char *
568 realloc (mem, n)
569      char *mem;
570      register unsigned int n;
571 {
572   register struct mhead *p;
573   register unsigned int tocopy;
574   register unsigned int nbytes;
575   register int nunits;
576
577   if ((p = (struct mhead *) mem) == 0)
578     return malloc (n);
579   p--;
580   nunits = p -> mh_index;
581   ASSERT (p -> mh_alloc == ISALLOC);
582 #ifdef RCHECK
583   ASSERT (p -> mh_magic4 == MAGIC4);
584   {
585     register char *m = mem + (tocopy = p -> mh_nbytes);
586     ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
587     ASSERT (*m++ == MAGIC1); ASSERT (*m   == MAGIC1);
588   }
589 #else /* not RCHECK */
590   if (p -> mh_index >= 13)
591     tocopy = (1 << (p -> mh_index + 3)) - sizeof *p;
592   else
593     tocopy = p -> mh_size;
594 #endif /* not RCHECK */
595
596   /* See if desired size rounds to same power of 2 as actual size. */
597   nbytes = (n + sizeof *p + EXTRA + 7) & ~7;
598
599   /* If ok, use the same block, just marking its size as changed.  */
600   if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
601     {
602 #ifdef RCHECK
603       register char *m = mem + tocopy;
604       *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;
605       p-> mh_nbytes = n;
606       m = mem + n;
607       *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;
608 #else /* not RCHECK */
609       p -> mh_size = n;
610 #endif /* not RCHECK */
611       return mem;
612     }
613
614   if (n < tocopy)
615     tocopy = n;
616   {
617     register char *new;
618
619     if ((new = malloc (n)) == 0)
620       return 0;
621     FASTCOPY (mem, new, tocopy);
622     free (mem);
623     return new;
624   }
625 }
626
627 char *
628 memalign (alignment, size)
629      unsigned int alignment, size;
630 {
631   register char *ptr;
632   register char *aligned;
633   register struct mhead *p;
634
635   ptr = malloc (size + alignment);
636
637   if (ptr == 0)
638     return 0;
639   /* If entire block has the desired alignment, just accept it.  */
640   if (((int) ptr & (alignment - 1)) == 0)
641     return ptr;
642   /* Otherwise, get address of byte in the block that has that alignment.  */
643   aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
644
645   /* Store a suitable indication of how to free the block,
646      so that free can find the true beginning of it.  */
647   p = (struct mhead *) aligned - 1;
648   p -> mh_size = aligned - ptr;
649   p -> mh_alloc = ISMEMALIGN;
650   return aligned;
651 }
652
653 #if !defined (HPUX)
654 /* This runs into trouble with getpagesize on HPUX, and Multimax machines.
655    Patching out seems cleaner than the ugly fix needed.  */
656 #if defined (__STDC__)
657 void *
658 #else
659 char *
660 #endif
661 valloc (size)
662      size_t size;
663 {
664   return memalign (getpagesize (), size);
665 }
666 #endif /* !HPUX */
667
668 #ifndef NO_CALLOC
669 char *
670 calloc (n, s)
671      size_t n, s;
672 {
673   size_t total;
674   char *result;
675
676   total = n * s;
677   result = malloc (total);
678   if (result)
679     zmemset (result, 0, total);
680   return result;  
681 }
682
683 void
684 cfree (p)
685      char *p;
686 {
687   free (p);
688 }
689 #endif /* !NO_CALLOC */
690
691 #ifdef MSTATS
692 /* Return statistics describing allocation of blocks of size 2**n. */
693
694 struct mstats_value
695   {
696     int blocksize;
697     int nfree;
698     int nused;
699   };
700
701 struct mstats_value
702 malloc_stats (size)
703      int size;
704 {
705   struct mstats_value v;
706   register int i;
707   register struct mhead *p;
708
709   v.nfree = 0;
710
711   if (size < 0 || size >= 30)
712     {
713       v.blocksize = 0;
714       v.nused = 0;
715       return v;
716     }
717
718   v.blocksize = 1 << (size + 3);
719   v.nused = nmalloc[size];
720
721   for (p = nextf[size]; p; p = CHAIN (p))
722     v.nfree++;
723
724   return v;
725 }
726 #endif /* MSTATS */
727
728 /*
729  *      This function returns the total number of bytes that the process
730  *      will be allowed to allocate via the sbrk(2) system call.  On
731  *      BSD systems this is the total space allocatable to stack and
732  *      data.  On USG systems this is the data space only.
733  */
734
735 #if !defined (HAVE_RESOURCE)
736 extern long ulimit ();
737
738 static void
739 get_lim_data ()
740 {    
741   lim_data = ulimit (3, 0);
742   lim_data -= (long) data_space_start;
743 }
744
745 #else /* HAVE_RESOURCE */
746 static void
747 get_lim_data ()
748 {
749   struct rlimit XXrlimit;
750
751   getrlimit (RLIMIT_DATA, &XXrlimit);
752 #ifdef RLIM_INFINITY
753   lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
754 #else
755   lim_data = XXrlimit.rlim_cur; /* soft limit */
756 #endif
757 }
758
759 #endif /* HAVE_RESOURCE */