summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortholo <>1997-01-05 22:12:48 +0000
committertholo <>1997-01-05 22:12:48 +0000
commitf91377cb68a99ddfc5e1e8936f4e360641981d6d (patch)
tree62b366a5aaf0f6d7d144c5bbed50d02a265486da
parenta6820ba482520797f3c1550fdfc95a3953b5252a (diff)
downloadopenbsd-f91377cb68a99ddfc5e1e8936f4e360641981d6d.tar.gz
openbsd-f91377cb68a99ddfc5e1e8936f4e360641981d6d.tar.bz2
openbsd-f91377cb68a99ddfc5e1e8936f4e360641981d6d.zip
Integrate latest malloc(3) from FreeBSD
-rw-r--r--src/lib/libc/stdlib/malloc.c388
1 files changed, 124 insertions, 264 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 1606ea6602..94db62c585 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.19 1996/11/24 00:41:30 niklas Exp $"; 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.20 1997/01/05 22:12:48 tholo Exp $";
12#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
13 13
14/* 14/*
@@ -18,17 +18,17 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.19 1996/11/24 00:41:30 niklas Exp
18 * any good unless you fiddle with the internals of malloc or want 18 * any good unless you fiddle with the internals of malloc or want
19 * to catch random pointer corruption as early as possible. 19 * to catch random pointer corruption as early as possible.
20 */ 20 */
21#undef EXTRA_SANITY 21#ifndef MALLOC_EXTRA_SANITY
22#undef MALLOC_EXTRA_SANITY
23#endif
22 24
23/* 25/*
24 * Defining MALLOC_STATS will enable you to call malloc_dump() and set 26 * Defining MALLOC_STATS will enable you to call malloc_dump() and set
25 * the [dD] options in the MALLOC_OPTIONS environment variable. 27 * the [dD] options in the MALLOC_OPTIONS environment variable.
26 * It has no run-time performance hit, but does pull in stdio... 28 * It has no run-time performance hit, but does pull in stdio...
27 */ 29 */
30#ifndef MALLOC_STATS
28#undef MALLOC_STATS 31#undef MALLOC_STATS
29
30#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS)
31# define MALLOC_STATS /* required for EXTRA_SANITY */
32#endif 32#endif
33 33
34/* 34/*
@@ -51,16 +51,24 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.19 1996/11/24 00:41:30 niklas Exp
51#include <sys/mman.h> 51#include <sys/mman.h>
52 52
53/* 53/*
54 * If these weren't defined here, they would be calculated on the fly, 54 * The basic parameters you can tweak.
55 * at a considerable cost in performance. 55 *
56 * malloc_pageshift pagesize = 1 << malloc_pageshift
57 * It's probably best if this is the native
58 * page size, but it shouldn't have to be.
59 *
60 * malloc_minsize minimum size of an allocation in bytes.
61 * If this is too small it's too much work
62 * to manage them. This is also the smallest
63 * unit of alignment used for the storage
64 * returned by malloc/realloc.
65 *
56 */ 66 */
57#ifdef __OpenBSD__ 67#ifdef __OpenBSD__
58# if defined(__alpha__) || defined(__m68k__) || defined(__mips__) || \ 68# if defined(__alpha__) || defined(__m68k__) || defined(__mips__) || \
59 defined(__i386__) || defined(__m88k__) || defined(__ns32k__) || \ 69 defined(__i386__) || defined(__m88k__) || defined(__ns32k__) || \
60 defined(__vax__) 70 defined(__vax__)
61# define malloc_pagesize (NBPG)
62# define malloc_pageshift (PGSHIFT) 71# define malloc_pageshift (PGSHIFT)
63# define malloc_maxsize (malloc_pagesize >> 1)
64# define malloc_minsize 16U 72# define malloc_minsize 16U
65# endif /* __i386__ */ 73# endif /* __i386__ */
66#endif /* __OpenBSD__ */ 74#endif /* __OpenBSD__ */
@@ -76,7 +84,7 @@ struct pginfo {
76 u_short shift; /* How far to shift for this size chunks */ 84 u_short shift; /* How far to shift for this size chunks */
77 u_short free; /* How many free chunks */ 85 u_short free; /* How many free chunks */
78 u_short total; /* How many chunk */ 86 u_short total; /* How many chunk */
79 u_long bits[1]; /* Which chunks are free */ 87 u_int bits[1]; /* Which chunks are free */
80}; 88};
81 89
82/* 90/*
@@ -92,10 +100,10 @@ struct pgfree {
92}; 100};
93 101
94/* 102/*
95 * How many bits per u_long in the bitmap. 103 * How many bits per u_int in the bitmap.
96 * Change only if not 8 bits/byte 104 * Change only if not 8 bits/byte
97 */ 105 */
98#define MALLOC_BITS (8*sizeof(u_long)) 106#define MALLOC_BITS (8*sizeof(u_int))
99 107
100/* 108/*
101 * Magic values to put in the page_directory 109 * Magic values to put in the page_directory
@@ -106,67 +114,29 @@ struct pgfree {
106#define MALLOC_FOLLOW ((struct pginfo*) 3) 114#define MALLOC_FOLLOW ((struct pginfo*) 3)
107#define MALLOC_MAGIC ((struct pginfo*) 4) 115#define MALLOC_MAGIC ((struct pginfo*) 4)
108 116
109/* 117#ifndef malloc_pageshift
110 * The i386 architecture has some very convenient instructions. 118#define malloc_pageshift 12U
111 * We might as well use them. There are C-language backups, but 119#endif
112 * they are considerably slower.
113 */
114#if defined(__i386__) && defined(__GNUC__)
115#define ffs _ffs
116static __inline int
117_ffs(input)
118 unsigned input;
119{
120 int result;
121 __asm("bsfl %1, %0" : "=r" (result) : "r" (input));
122 return result+1;
123}
124
125#define fls _fls
126static __inline int
127_fls(input)
128 unsigned input;
129{
130 int result;
131 __asm("bsrl %1, %0" : "=r" (result) : "r" (input));
132 return result+1;
133}
134 120
135#define set_bit _set_bit 121#ifndef malloc_minsize
136static __inline void 122#define malloc_minsize 16U
137_set_bit(pi, bit) 123#endif
138 struct pginfo *pi;
139 int bit;
140{
141 __asm("btsl %0, (%1)" :
142 : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
143}
144 124
145#define clr_bit _clr_bit 125#ifndef malloc_pageshift
146static __inline void 126#error "malloc_pageshift undefined"
147_clr_bit(pi, bit) 127#endif
148 struct pginfo *pi;
149 int bit;
150{
151 __asm("btcl %0, (%1)" :
152 : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
153}
154 128
155#endif /* __i386__ && __GNUC__ */ 129#if !defined(malloc_pagesize)
130#define malloc_pagesize (1U<<malloc_pageshift)
131#endif
156 132
157/* 133#if ((1<<malloc_pageshift) != malloc_pagesize)
158 * Set to one when malloc_init has been called 134#error "(1<<malloc_pageshift) != malloc_pagesize"
159 */ 135#endif
160static unsigned initialized;
161 136
162/* 137#ifndef malloc_maxsize
163 * The size of a page. 138#define malloc_maxsize ((malloc_pagesize)>>1)
164 * Must be a integral multiplum of the granularity of mmap(2). 139#endif
165 * Your toes will curl if it isn't a power of two
166 */
167#ifndef malloc_pagesize
168static unsigned malloc_pagesize;
169#endif /* malloc_pagesize */
170 140
171/* A mask for the offset inside a page. */ 141/* A mask for the offset inside a page. */
172#define malloc_pagemask ((malloc_pagesize)-1) 142#define malloc_pagemask ((malloc_pagesize)-1)
@@ -174,45 +144,26 @@ static unsigned malloc_pagesize;
174#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask))) 144#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
175#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo) 145#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
176 146
177/* malloc_pagesize == 1 << malloc_pageshift */ 147/* Set when initialization has been done */
178#ifndef malloc_pageshift 148static unsigned malloc_started;
179static unsigned malloc_pageshift;
180#endif /* malloc_pageshift */
181 149
182/* 150/* Number of free pages we cache */
183 * The smallest allocation we bother about. 151static unsigned malloc_cache = 16;
184 * Must be power of two
185 */
186#ifndef malloc_minsize
187static unsigned malloc_minsize;
188#endif /* malloc_minsize */
189
190/*
191 * The largest chunk we care about.
192 * Must be smaller than pagesize
193 * Must be power of two
194 */
195#ifndef malloc_maxsize
196static unsigned malloc_maxsize;
197#endif /* malloc_maxsize */
198
199/* The minimum size (in pages) of the free page cache. */
200static unsigned malloc_cache = 16;
201 152
202/* The offset from pagenumber to index into the page directory */ 153/* The offset from pagenumber to index into the page directory */
203static u_long malloc_origo; 154static u_long malloc_origo;
204 155
205/* The last index in the page directory we care about */ 156/* The last index in the page directory we care about */
206static u_long last_index; 157static u_long last_index;
207 158
208/* Pointer to page directory. Allocated "as if with" malloc */ 159/* Pointer to page directory. Allocated "as if with" malloc */
209static struct pginfo **page_dir; 160static struct pginfo **page_dir;
210 161
211/* How many slots in the page directory */ 162/* How many slots in the page directory */
212static unsigned malloc_ninfo; 163static unsigned malloc_ninfo;
213 164
214/* Free pages line up here */ 165/* Free pages line up here */
215static struct pgfree free_list; 166static struct pgfree free_list;
216 167
217/* Abort(), user doesn't handle problems. */ 168/* Abort(), user doesn't handle problems. */
218static int malloc_abort; 169static int malloc_abort;
@@ -223,7 +174,7 @@ static int suicide;
223#ifdef MALLOC_STATS 174#ifdef MALLOC_STATS
224/* dump statistics */ 175/* dump statistics */
225static int malloc_stats; 176static int malloc_stats;
226#endif /* MALLOC_STATS */ 177#endif
227 178
228/* always realloc ? */ 179/* always realloc ? */
229static int malloc_realloc; 180static int malloc_realloc;
@@ -245,6 +196,8 @@ static int malloc_utrace;
245 196
246struct ut { void *p; size_t s; void *r; }; 197struct ut { void *p; size_t s; void *r; };
247 198
199void utrace __P((struct ut *, int));
200
248#define UTRACE(a, b, c) \ 201#define UTRACE(a, b, c) \
249 if (malloc_utrace) \ 202 if (malloc_utrace) \
250 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);} 203 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
@@ -261,6 +214,9 @@ static struct pgfree *px;
261/* compile-time options */ 214/* compile-time options */
262char *malloc_options; 215char *malloc_options;
263 216
217/* Name of the current public function */
218static char *malloc_func;
219
264/* 220/*
265 * Necessary function declarations 221 * Necessary function declarations
266 */ 222 */
@@ -328,16 +284,17 @@ malloc_dump(fd)
328} 284}
329#endif /* MALLOC_STATS */ 285#endif /* MALLOC_STATS */
330 286
331static char *malloc_func; 287extern char *__progname;
332 288
333static void 289static void
334wrterror(p) 290wrterror(p)
335 char *p; 291 char *p;
336{ 292{
337 char *q = "Malloc error: "; 293 char *q = " error: ";
338 suicide = 1; 294 suicide = 1;
339 write(2, q, strlen(q)); 295 write(2, __progname, strlen(__progname));
340 write(2, malloc_func, strlen(malloc_func)); 296 write(2, malloc_func, strlen(malloc_func));
297 write(2, q, strlen(q));
341 write(2, p, strlen(p)); 298 write(2, p, strlen(p));
342#ifdef MALLOC_STATS 299#ifdef MALLOC_STATS
343 if (malloc_stats) 300 if (malloc_stats)
@@ -350,15 +307,16 @@ static void
350wrtwarning(p) 307wrtwarning(p)
351 char *p; 308 char *p;
352{ 309{
353 char *q = "Malloc warning: "; 310 char *q = " warning: ";
354 if (malloc_abort) 311 if (malloc_abort)
355 wrterror(p); 312 wrterror(p);
356 write(2, q, strlen(q)); 313 write(2, __progname, strlen(__progname));
357 write(2, malloc_func, strlen(malloc_func)); 314 write(2, malloc_func, strlen(malloc_func));
315 write(2, q, strlen(q));
358 write(2, p, strlen(p)); 316 write(2, p, strlen(p));
359} 317}
360 318
361#ifdef EXTRA_SANITY 319#ifdef MALLOC_STATS
362static void 320static void
363malloc_exit() 321malloc_exit()
364{ 322{
@@ -370,7 +328,7 @@ malloc_exit()
370 } else 328 } else
371 write(2, q, strlen(q)); 329 write(2, q, strlen(q));
372} 330}
373#endif /* EXTRA_SANITY */ 331#endif /* MALLOC_STATS */
374 332
375 333
376/* 334/*
@@ -402,83 +360,6 @@ map_pages(pages)
402} 360}
403 361
404/* 362/*
405 * Set a bit in the bitmap
406 */
407#ifndef set_bit
408static __inline void
409set_bit(pi, bit)
410 struct pginfo *pi;
411 int bit;
412{
413 pi->bits[bit/MALLOC_BITS] |= 1UL<<(bit%MALLOC_BITS);
414}
415#endif /* set_bit */
416
417/*
418 * Clear a bit in the bitmap
419 */
420#ifndef clr_bit
421static __inline void
422clr_bit(pi, bit)
423 struct pginfo *pi;
424 int bit;
425{
426 pi->bits[bit/MALLOC_BITS] &= ~(1UL<<(bit%MALLOC_BITS));
427}
428#endif /* clr_bit */
429
430#ifndef tst_bit
431/*
432 * Test a bit in the bitmap
433 */
434static __inline int
435tst_bit(pi, bit)
436 struct pginfo *pi;
437 int bit;
438{
439 return pi->bits[bit/MALLOC_BITS] & (1UL<<(bit%MALLOC_BITS));
440}
441#endif /* tst_bit */
442
443/*
444 * Find last bit
445 */
446#ifndef fls
447static __inline int
448fls(size)
449 size_t size;
450{
451 int i = 1;
452 while (size >>= 1)
453 i++;
454 return i;
455}
456#endif /* fls */
457
458#if LONG_BIT == WORD_BIT
459#define ffs_ul ffs
460#else
461static __inline int
462ffs_ul(u_long ul)
463{
464 u_int n;
465 int i;
466 int k;
467
468 for (i = 0; i < sizeof (u_long) / sizeof (u_int); i++) {
469 n = ul & UINT_MAX;
470 k = ffs (n);
471 if (k)
472 break;
473 ul >>= (sizeof (u_int) * 8);
474 }
475 if (k)
476 k += i * sizeof (u_int) * 8;
477 return k;
478}
479#endif
480
481/*
482 * Extend page directory 363 * Extend page directory
483 */ 364 */
484static int 365static int
@@ -556,11 +437,9 @@ malloc_init ()
556 p = b; 437 p = b;
557 } else if (i == 1 && issetugid() == 0) { 438 } else if (i == 1 && issetugid() == 0) {
558 p = getenv("MALLOC_OPTIONS"); 439 p = getenv("MALLOC_OPTIONS");
559 } else if (i == 2) { 440 } else {
560 p = malloc_options; 441 p = malloc_options;
561 } 442 }
562 else
563 p = NULL;
564 for (; p && *p; p++) { 443 for (; p && *p; p++) {
565 switch (*p) { 444 switch (*p) {
566 case '>': malloc_cache <<= 1; break; 445 case '>': malloc_cache <<= 1; break;
@@ -604,53 +483,10 @@ malloc_init ()
604 if (malloc_zero) 483 if (malloc_zero)
605 malloc_junk=1; 484 malloc_junk=1;
606 485
607#ifdef EXTRA_SANITY 486#ifdef MALLOC_STATS
608 if (malloc_stats) 487 if (malloc_stats)
609 atexit(malloc_exit); 488 atexit(malloc_exit);
610#endif /* EXTRA_SANITY */ 489#endif /* MALLOC_STATS */
611
612#ifndef malloc_pagesize
613 /* determine our pagesize */
614 malloc_pagesize = getpagesize();
615#endif /* malloc_pagesize */
616
617#ifndef malloc_maxsize
618 malloc_maxsize = malloc_pagesize >> 1;
619#endif /* malloc_maxsize */
620
621#ifndef malloc_pageshift
622 {
623 int i;
624 /* determine how much we shift by to get there */
625 for (i = malloc_pagesize; i > 1; i >>= 1)
626 malloc_pageshift++;
627 }
628#endif /* malloc_pageshift */
629
630#ifndef malloc_minsize
631 {
632 int i;
633 /*
634 * find the smallest size allocation we will bother about.
635 * this is determined as the smallest allocation that can hold
636 * it's own pginfo;
637 */
638 i = 2;
639 for(;;) {
640 int j;
641
642 /* Figure out the size of the bits */
643 j = malloc_pagesize/i;
644 j /= 8;
645 if (j < sizeof(u_long))
646 j = sizeof (u_long);
647 if (sizeof(struct pginfo) + j - sizeof (u_long) <= i)
648 break;
649 i += i;
650 }
651 malloc_minsize = i;
652 }
653#endif /* malloc_minsize */
654 490
655 /* Allocate one page for the page directory */ 491 /* Allocate one page for the page directory */
656 page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE, 492 page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE,
@@ -668,7 +504,14 @@ malloc_init ()
668 malloc_ninfo = malloc_pagesize / sizeof *page_dir; 504 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
669 505
670 /* Been here, done that */ 506 /* Been here, done that */
671 initialized++; 507 malloc_started++;
508
509 /* Recalculate the cache size in bytes, and make sure it's nonzero */
510
511 if (!malloc_cache)
512 malloc_cache++;
513
514 malloc_cache <<= malloc_pageshift;
672 515
673 /* 516 /*
674 * This is a nice hack from Kaleb Keithly (kaleb@x.org). 517 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
@@ -676,16 +519,12 @@ malloc_init ()
676 */ 519 */
677 px = (struct pgfree *) imalloc (sizeof *px); 520 px = (struct pgfree *) imalloc (sizeof *px);
678 521
679 if (!malloc_cache)
680 malloc_cache++;
681
682 malloc_cache <<= malloc_pageshift;
683} 522}
684 523
685/* 524/*
686 * Allocate a number of complete pages 525 * Allocate a number of complete pages
687 */ 526 */
688void * 527static void *
689malloc_pages(size) 528malloc_pages(size)
690 size_t size; 529 size_t size;
691{ 530{
@@ -771,7 +610,7 @@ malloc_pages(size)
771 * Allocate a page of fragments 610 * Allocate a page of fragments
772 */ 611 */
773 612
774static __inline int 613static __inline__ int
775malloc_make_chunks(bits) 614malloc_make_chunks(bits)
776 int bits; 615 int bits;
777{ 616{
@@ -794,8 +633,10 @@ malloc_make_chunks(bits)
794 bp = (struct pginfo *)pp; 633 bp = (struct pginfo *)pp;
795 } else { 634 } else {
796 bp = (struct pginfo *)imalloc(l); 635 bp = (struct pginfo *)imalloc(l);
797 if (!bp) 636 if (!bp) {
637 ifree(pp);
798 return 0; 638 return 0;
639 }
799 } 640 }
800 641
801 bp->size = (1UL<<bits); 642 bp->size = (1UL<<bits);
@@ -803,12 +644,7 @@ malloc_make_chunks(bits)
803 bp->total = bp->free = malloc_pagesize >> bits; 644 bp->total = bp->free = malloc_pagesize >> bits;
804 bp->page = pp; 645 bp->page = pp;
805 646
806 page_dir[ptr2index(pp)] = bp; 647 /* set all valid bits in the bitmap */
807
808 bp->next = page_dir[bits];
809 page_dir[bits] = bp;
810
811 /* set all valid bits in the bits */
812 k = bp->total; 648 k = bp->total;
813 i = 0; 649 i = 0;
814 650
@@ -817,18 +653,27 @@ malloc_make_chunks(bits)
817 bp->bits[i / MALLOC_BITS] = (u_long)~0; 653 bp->bits[i / MALLOC_BITS] = (u_long)~0;
818 654
819 for(; i < k; i++) 655 for(; i < k; i++)
820 set_bit(bp, i); 656 bp->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
821 657
822 if (bp == bp->page) { 658 if (bp == bp->page) {
823 /* Mark the ones we stole for ourselves */ 659 /* Mark the ones we stole for ourselves */
824 for(i=0;l > 0;i++) { 660 for(i=0;l > 0;i++) {
825 clr_bit(bp, i); 661 bp->bits[i/MALLOC_BITS] &= ~(1<<(i%MALLOC_BITS));
826 bp->free--; 662 bp->free--;
827 bp->total--; 663 bp->total--;
828 l -= (1 << bits); 664 l -= (1 << bits);
829 } 665 }
830 } 666 }
831 667
668 /* MALLOC_LOCK */
669
670 page_dir[ptr2index(pp)] = bp;
671
672 bp->next = page_dir[bits];
673 page_dir[bits] = bp;
674
675 /* MALLOC_UNLOCK */
676
832 return 1; 677 return 1;
833} 678}
834 679
@@ -839,17 +684,21 @@ static void *
839malloc_bytes(size) 684malloc_bytes(size)
840 size_t size; 685 size_t size;
841{ 686{
842 int j; 687 int i,j;
688 u_int u;
843 struct pginfo *bp; 689 struct pginfo *bp;
844 int k; 690 int k;
845 u_long *lp; 691 u_int *lp;
846 692
847 /* Don't bother with anything less than this */ 693 /* Don't bother with anything less than this */
848 if (size < malloc_minsize) 694 if (size < malloc_minsize)
849 size = malloc_minsize; 695 size = malloc_minsize;
850 696
851 /* Find the right bucket */ 697 /* Find the right bucket */
852 j = fls((size)-1); 698 j = 1;
699 i = size-1;
700 while (i >>= 1)
701 j++;
853 702
854 /* If it's empty, make a page more of that size chunks */ 703 /* If it's empty, make a page more of that size chunks */
855 if (!page_dir[j] && !malloc_make_chunks(j)) 704 if (!page_dir[j] && !malloc_make_chunks(j))
@@ -862,8 +711,13 @@ malloc_bytes(size)
862 ; 711 ;
863 712
864 /* Find that bit, and tweak it */ 713 /* Find that bit, and tweak it */
865 k = ffs_ul(*lp) - 1; 714 u = 1;
866 *lp ^= 1UL<<k; 715 k = 0;
716 while (!(*lp & u)) {
717 u += u;
718 k++;
719 }
720 *lp ^= u;
867 721
868 /* If there are no more free, remove from free-list */ 722 /* If there are no more free, remove from free-list */
869 if (!--bp->free) { 723 if (!--bp->free) {
@@ -878,7 +732,7 @@ malloc_bytes(size)
878 if (malloc_junk) 732 if (malloc_junk)
879 memset((char *)bp->page + k, SOME_JUNK, bp->size); 733 memset((char *)bp->page + k, SOME_JUNK, bp->size);
880 734
881 return (void *)((char *)bp->page + k); 735 return (u_char *)bp->page + k;
882} 736}
883 737
884/* 738/*
@@ -893,7 +747,7 @@ imalloc(size)
893 int status; 747 int status;
894#endif 748#endif
895 749
896 if (!initialized) 750 if (!malloc_started)
897 malloc_init(); 751 malloc_init();
898 752
899 if (suicide) 753 if (suicide)
@@ -907,7 +761,7 @@ imalloc(size)
907 if (malloc_abort && !result) 761 if (malloc_abort && !result)
908 wrterror("allocation failed.\n"); 762 wrterror("allocation failed.\n");
909 763
910 if (malloc_zero) 764 if (malloc_zero && result)
911 memset(result, 0, size); 765 memset(result, 0, size);
912 766
913 return result; 767 return result;
@@ -932,7 +786,7 @@ irealloc(ptr, size)
932 if (suicide) 786 if (suicide)
933 return 0; 787 return 0;
934 788
935 if (!initialized) { 789 if (!malloc_started) {
936 wrtwarning("malloc() has never been called.\n"); 790 wrtwarning("malloc() has never been called.\n");
937 return 0; 791 return 0;
938 } 792 }
@@ -981,7 +835,7 @@ irealloc(ptr, size)
981 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift; 835 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
982 836
983 /* Verify that it isn't a free chunk already */ 837 /* Verify that it isn't a free chunk already */
984 if (tst_bit(*mp, i)) { 838 if ((*mp)->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
985 wrtwarning("chunk is already free.\n"); 839 wrtwarning("chunk is already free.\n");
986 return 0; 840 return 0;
987 } 841 }
@@ -1017,7 +871,7 @@ irealloc(ptr, size)
1017 * Free a sequence of pages 871 * Free a sequence of pages
1018 */ 872 */
1019 873
1020static __inline void 874static __inline__ void
1021free_pages(ptr, index, info) 875free_pages(ptr, index, info)
1022 void *ptr; 876 void *ptr;
1023 int index; 877 int index;
@@ -1050,6 +904,9 @@ free_pages(ptr, index, info)
1050 904
1051 l = i << malloc_pageshift; 905 l = i << malloc_pageshift;
1052 906
907 if (malloc_junk)
908 memset(ptr, SOME_JUNK, l);
909
1053#ifdef __FreeBSD__ 910#ifdef __FreeBSD__
1054 if (malloc_hint) 911 if (malloc_hint)
1055 madvise(ptr, l, MADV_FREE); 912 madvise(ptr, l, MADV_FREE);
@@ -1150,7 +1007,7 @@ free_pages(ptr, index, info)
1150 */ 1007 */
1151 1008
1152/* ARGSUSED */ 1009/* ARGSUSED */
1153static __inline void 1010static __inline__ void
1154free_bytes(ptr, index, info) 1011free_bytes(ptr, index, info)
1155 void *ptr; 1012 void *ptr;
1156 int index; 1013 int index;
@@ -1168,12 +1025,15 @@ free_bytes(ptr, index, info)
1168 return; 1025 return;
1169 } 1026 }
1170 1027
1171 if (tst_bit(info, i)) { 1028 if (info->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
1172 wrtwarning("chunk is already free.\n"); 1029 wrtwarning("chunk is already free.\n");
1173 return; 1030 return;
1174 } 1031 }
1175 1032
1176 set_bit(info, i); 1033 if (malloc_junk)
1034 memset(ptr, SOME_JUNK, info->size);
1035
1036 info->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
1177 info->free++; 1037 info->free++;
1178 1038
1179 mp = page_dir + info->shift; 1039 mp = page_dir + info->shift;
@@ -1226,7 +1086,7 @@ ifree(ptr)
1226 if (!ptr) 1086 if (!ptr)
1227 return; 1087 return;
1228 1088
1229 if (!initialized) { 1089 if (!malloc_started) {
1230 wrtwarning("malloc() has never been called.\n"); 1090 wrtwarning("malloc() has never been called.\n");
1231 return; 1091 return;
1232 } 1092 }
@@ -1265,7 +1125,7 @@ ifree(ptr)
1265#include "pthread_private.h" 1125#include "pthread_private.h"
1266static int malloc_lock; 1126static int malloc_lock;
1267#define THREAD_LOCK() _thread_kern_sig_block(&malloc_lock); 1127#define THREAD_LOCK() _thread_kern_sig_block(&malloc_lock);
1268#define THREAD_UNLOCK() _thread_kern_sig_unblock(&malloc_lock); 1128#define THREAD_UNLOCK() _thread_kern_sig_unblock(malloc_lock);
1269#else 1129#else
1270#define THREAD_LOCK() 1130#define THREAD_LOCK()
1271#define THREAD_UNLOCK() 1131#define THREAD_UNLOCK()
@@ -1278,7 +1138,7 @@ malloc(size_t size)
1278{ 1138{
1279 register void *r; 1139 register void *r;
1280 1140
1281 malloc_func = "malloc():"; 1141 malloc_func = " in malloc():";
1282 THREAD_LOCK(); 1142 THREAD_LOCK();
1283 if (malloc_active++) { 1143 if (malloc_active++) {
1284 wrtwarning("recursive call.\n"); 1144 wrtwarning("recursive call.\n");
@@ -1295,7 +1155,7 @@ malloc(size_t size)
1295void 1155void
1296free(void *ptr) 1156free(void *ptr)
1297{ 1157{
1298 malloc_func = "free():"; 1158 malloc_func = " in free():";
1299 THREAD_LOCK(); 1159 THREAD_LOCK();
1300 if (malloc_active++) { 1160 if (malloc_active++) {
1301 wrtwarning("recursive call.\n"); 1161 wrtwarning("recursive call.\n");
@@ -1314,7 +1174,7 @@ realloc(void *ptr, size_t size)
1314{ 1174{
1315 register void *r; 1175 register void *r;
1316 1176
1317 malloc_func = "realloc():"; 1177 malloc_func = " in realloc():";
1318 THREAD_LOCK(); 1178 THREAD_LOCK();
1319 if (malloc_active++) { 1179 if (malloc_active++) {
1320 wrtwarning("recursive call.\n"); 1180 wrtwarning("recursive call.\n");