This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[inseparable changes from patch from perl5.003_07 to perl5.003_08]
[perl5.git] / malloc.c
CommitLineData
a0d0e21e 1/* malloc.c
8d063cd8 2 *
8d063cd8
LW
3 */
4
5#ifndef lint
a687059c 6#ifdef DEBUGGING
8d063cd8 7#define RCHECK
a687059c 8#endif
8d063cd8
LW
9/*
10 * malloc.c (Caltech) 2/21/82
11 * Chris Kingsley, kingsley@cit-20.
12 *
13 * This is a very fast storage allocator. It allocates blocks of a small
14 * number of different sizes, and keeps free lists of each size. Blocks that
15 * don't exactly fit are passed up to the next larger size. In this
16 * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
cf5c4ad8 17 * If PACK_MALLOC is defined, small blocks are 2^n bytes long.
8d063cd8
LW
18 * This is designed for use in a program that uses vast quantities of memory,
19 * but bombs when it runs out.
20 */
21
135863df 22#include "EXTERN.h"
135863df
AB
23#include "perl.h"
24
760ac839
LW
25#ifdef DEBUGGING
26#undef DEBUG_m
27#define DEBUG_m(a) if (debug & 128) a
28#endif
29
135863df
AB
30/* I don't much care whether these are defined in sys/types.h--LAW */
31
32#define u_char unsigned char
33#define u_int unsigned int
34#define u_short unsigned short
8d063cd8 35
cf5c4ad8 36/* 286 and atarist like big chunks, which gives too much overhead. */
37#if (defined(RCHECK) || defined(I286) || defined(atarist)) && defined(PACK_MALLOC)
38#undef PACK_MALLOC
39#endif
40
41
8d063cd8 42/*
cf5c4ad8 43 * The description below is applicable if PACK_MALLOC is not defined.
44 *
8d063cd8
LW
45 * The overhead on a block is at least 4 bytes. When free, this space
46 * contains a pointer to the next free block, and the bottom two bits must
47 * be zero. When in use, the first byte is set to MAGIC, and the second
48 * byte is the size index. The remaining bytes are for alignment.
49 * If range checking is enabled and the size of the block fits
50 * in two bytes, then the top two bytes hold the size of the requested block
51 * plus the range checking words, and the header word MINUS ONE.
52 */
53union overhead {
54 union overhead *ov_next; /* when free */
85e6fe83 55#if MEM_ALIGNBYTES > 4
c623bd54 56 double strut; /* alignment problems */
a687059c 57#endif
8d063cd8
LW
58 struct {
59 u_char ovu_magic; /* magic number */
60 u_char ovu_index; /* bucket # */
61#ifdef RCHECK
62 u_short ovu_size; /* actual block size */
63 u_int ovu_rmagic; /* range magic number */
64#endif
65 } ovu;
66#define ov_magic ovu.ovu_magic
67#define ov_index ovu.ovu_index
68#define ov_size ovu.ovu_size
69#define ov_rmagic ovu.ovu_rmagic
70};
71
760ac839 72#ifdef DEBUGGING
a0d0e21e
LW
73static void botch _((char *s));
74#endif
75static void morecore _((int bucket));
76static int findbucket _((union overhead *freep, int srchlen));
77
8d063cd8
LW
78#define MAGIC 0xff /* magic # on accounting info */
79#define RMAGIC 0x55555555 /* magic # on range info */
80#ifdef RCHECK
81#define RSLOP sizeof (u_int)
82#else
83#define RSLOP 0
84#endif
85
cf5c4ad8 86#ifdef PACK_MALLOC
87/*
88 * In this case it is assumed that if we do sbrk() in 2K units, we
89 * will get 2K aligned blocks. The bucket number of the given subblock is
90 * on the boundary of 2K block which contains the subblock.
91 * Several following bytes contain the magic numbers for the subblocks
92 * in the block.
93 *
94 * Sizes of chunks are powers of 2 for chunks in buckets <=
95 * MAX_PACKED, after this they are (2^n - sizeof(union overhead)) (to
96 * get alignment right).
97 *
98 * We suppose that starts of all the chunks in a 2K block are in
99 * different 2^n-byte-long chunks. If the top of the last chunk is
100 * aligned on a boundary of 2K block, this means that
101 * sizeof(union overhead)*"number of chunks" < 2^n, or
102 * sizeof(union overhead)*2K < 4^n, or n > 6 + log2(sizeof()/2)/2, if a
103 * chunk of size 2^n - overhead is used. Since this rules out n = 7
104 * for 8 byte alignment, we specialcase allocation of the first of 16
105 * 128-byte-long chunks.
106 *
107 * Note that with the above assumption we automatically have enough
108 * place for MAGIC at the start of 2K block. Note also that we
109 * overlay union overhead over the chunk, thus the start of the chunk
110 * is immediately overwritten after freeing.
111 */
112# define MAX_PACKED 6
113# define MAX_2_POT_ALGO ((1<<(MAX_PACKED + 1)) - M_OVERHEAD)
114# define TWOK_MASK ((1<<11) - 1)
115# define TWOK_MASKED(x) ((int)x & ~TWOK_MASK)
116# define TWOK_SHIFT(x) ((int)x & TWOK_MASK)
117# define OV_INDEXp(block) ((u_char*)(TWOK_MASKED(block)))
118# define OV_INDEX(block) (*OV_INDEXp(block))
119# define OV_MAGIC(block,bucket) (*(OV_INDEXp(block) + \
120 (TWOK_SHIFT(block)>>(bucket + 3)) + \
121 (bucket > MAX_NONSHIFT ? 1 : 0)))
122# define CHUNK_SHIFT 0
123
124static u_char n_blks[11 - 3] = {224, 120, 62, 31, 16, 8, 4, 2};
125static u_short blk_shift[11 - 3] = {256, 128, 64, 32,
126 16*sizeof(union overhead),
127 8*sizeof(union overhead),
128 4*sizeof(union overhead),
129 2*sizeof(union overhead),
130# define MAX_NONSHIFT 2 /* Shift 64 greater than chunk 32. */
131};
132
133# ifdef DEBUGGING_MSTATS
134static u_int sbrk_slack;
135static u_int start_slack;
136# endif
137
138#else /* !PACK_MALLOC */
139
140# define OV_MAGIC(block,bucket) (block)->ov_magic
141# define OV_INDEX(block) (block)->ov_index
142# define CHUNK_SHIFT 1
143#endif /* !PACK_MALLOC */
144
145# define M_OVERHEAD (sizeof(union overhead) + RSLOP)
146
8d063cd8 147/*
55497cff 148 * Big allocations are often of the size 2^n bytes. To make them a
149 * little bit better, make blocks of size 2^n+pagesize for big n.
150 */
151
152#ifdef TWO_POT_OPTIMIZE
153
154# define PERL_PAGESIZE 4096
155# define FIRST_BIG_TWO_POT 14 /* 16K */
156# define FIRST_BIG_BLOCK (1<<FIRST_BIG_TWO_POT) /* 16K */
157/* If this value or more, check against bigger blocks. */
158# define FIRST_BIG_BOUND (FIRST_BIG_BLOCK - M_OVERHEAD)
159/* If less than this value, goes into 2^n-overhead-block. */
160# define LAST_SMALL_BOUND ((FIRST_BIG_BLOCK>>1) - M_OVERHEAD)
161
162#endif /* TWO_POT_OPTIMIZE */
163
164#ifdef PERL_EMERGENCY_SBRK
165
166#ifndef BIG_SIZE
167# define BIG_SIZE (1<<16) /* 64K */
168#endif
169
170static char *emergency_buffer;
171static MEM_SIZE emergency_buffer_size;
172
173static char *
174emergency_sbrk(size)
175 MEM_SIZE size;
176{
177 if (size >= BIG_SIZE) {
178 /* Give the possibility to recover: */
179 die("Out of memory during request for %i bytes", size);
180 /* croak may eat too much memory. */
181 }
182
183 if (!emergency_buffer) {
184 /* First offense, give a possibility to recover by dieing. */
185 /* No malloc involved here: */
186 GV **gvp = (GV**)hv_fetch(defstash, "^M", 2, 0);
187 SV *sv;
188 char *pv;
189
190 if (!gvp) gvp = (GV**)hv_fetch(defstash, "\015", 1, 0);
191 if (!gvp || !(sv = GvSV(*gvp)) || !SvPOK(sv)
192 || (SvLEN(sv) < (1<<11) - M_OVERHEAD))
193 return (char *)-1; /* Now die die die... */
194
195 /* Got it, now detach SvPV: */
196 pv = SvPV(sv);
197 /* Check alignment: */
198 if ((pv - M_OVERHEAD) & (1<<11 - 1)) {
199 PerlIO_puts(PerlIO_stderr(),"Bad alignment of $^M!\n");
200 return -1; /* die die die */
201 }
202
203 emergency_buffer = pv - M_OVERHEAD;
204 emergency_buffer_size = SvLEN(sv) + M_OVERHEAD;
205 SvPOK_off(sv);
206 SvREADONLY_on(sv);
207 die("Out of memory!"); /* croak may eat too much memory. */
208 } else if (emergency_buffer_size >= size) {
209 emergency_buffer_size -= size;
210 return emergency_buffer + emergency_buffer_size;
211 }
212
213 return (char *)-1; /* poor guy... */
214}
215
216#else /* !PERL_EMERGENCY_SBRK */
217# define emergency_sbrk(size) -1
218#endif /* !PERL_EMERGENCY_SBRK */
219
220/*
8d063cd8
LW
221 * nextf[i] is the pointer to the next free block of size 2^(i+3). The
222 * smallest allocatable block is 8 bytes. The overhead information
223 * precedes the data area returned to the user.
224 */
225#define NBUCKETS 30
226static union overhead *nextf[NBUCKETS];
cf5c4ad8 227
228#ifdef USE_PERL_SBRK
229#define sbrk(a) Perl_sbrk(a)
230char * Perl_sbrk _((int size));
231#else
8d063cd8 232extern char *sbrk();
cf5c4ad8 233#endif
8d063cd8 234
c07a80fd 235#ifdef DEBUGGING_MSTATS
8d063cd8
LW
236/*
237 * nmalloc[i] is the difference between the number of mallocs and frees
238 * for a given block size.
239 */
240static u_int nmalloc[NBUCKETS];
8d063cd8
LW
241#endif
242
760ac839 243#ifdef DEBUGGING
4dfc412b 244#define ASSERT(p) if (!(p)) botch(STRINGIFY(p)); else
ee0007ab 245static void
8d063cd8
LW
246botch(s)
247 char *s;
248{
4dfc412b 249 PerlIO_printf(PerlIO_stderr(), "assertion botched: %s\n", s);
8d063cd8
LW
250 abort();
251}
252#else
253#define ASSERT(p)
254#endif
255
2304df62 256Malloc_t
8d063cd8 257malloc(nbytes)
ee0007ab 258 register MEM_SIZE nbytes;
8d063cd8
LW
259{
260 register union overhead *p;
261 register int bucket = 0;
ee0007ab 262 register MEM_SIZE shiftr;
8d063cd8 263
55497cff 264#ifdef PERL_CORE
45d8adaa 265#ifdef DEBUGGING
ee0007ab 266 MEM_SIZE size = nbytes;
45d8adaa
LW
267#endif
268
55497cff 269#ifdef HAS_64K_LIMIT
45d8adaa 270 if (nbytes > 0xffff) {
760ac839 271 PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", (long)nbytes);
79072805 272 my_exit(1);
45d8adaa 273 }
55497cff 274#endif /* HAS_64K_LIMIT */
45d8adaa
LW
275#ifdef DEBUGGING
276 if ((long)nbytes < 0)
463ee0b2 277 croak("panic: malloc");
45d8adaa 278#endif
55497cff 279#endif /* PERL_CORE */
45d8adaa 280
8d063cd8
LW
281 /*
282 * Convert amount of memory requested into
283 * closest block size stored in hash buckets
284 * which satisfies request. Account for
285 * space used per block for accounting.
286 */
cf5c4ad8 287#ifdef PACK_MALLOC
288 if (nbytes > MAX_2_POT_ALGO) {
289#endif
55497cff 290#ifdef TWO_POT_OPTIMIZE
291 if (nbytes >= FIRST_BIG_BOUND) {
292 nbytes -= PERL_PAGESIZE;
293 }
294#endif
cf5c4ad8 295 nbytes += M_OVERHEAD;
296 nbytes = (nbytes + 3) &~ 3;
297#ifdef PACK_MALLOC
298 } else if (nbytes == 0) {
299 nbytes = 1;
300 }
301#endif
8d063cd8
LW
302 shiftr = (nbytes - 1) >> 2;
303 /* apart from this loop, this is O(1) */
304 while (shiftr >>= 1)
305 bucket++;
306 /*
307 * If nothing in hash bucket right now,
308 * request more memory from the system.
309 */
310 if (nextf[bucket] == NULL)
311 morecore(bucket);
45d8adaa 312 if ((p = (union overhead *)nextf[bucket]) == NULL) {
55497cff 313#ifdef PERL_CORE
ee0007ab 314 if (!nomemok) {
760ac839 315 PerlIO_puts(PerlIO_stderr(),"Out of memory!\n");
79072805 316 my_exit(1);
ee0007ab 317 }
45d8adaa 318#else
8d063cd8 319 return (NULL);
45d8adaa
LW
320#endif
321 }
322
55497cff 323#ifdef PERL_CORE
760ac839 324 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",
a0d0e21e 325 (unsigned long)(p+1),an++,(long)size));
55497cff 326#endif /* PERL_CORE */
45d8adaa 327
8d063cd8 328 /* remove from linked list */
bf38876a
LW
329#ifdef RCHECK
330 if (*((int*)p) & (sizeof(union overhead) - 1))
760ac839 331 PerlIO_printf(PerlIO_stderr(), "Corrupt malloc ptr 0x%lx at 0x%lx\n",
a0d0e21e 332 (unsigned long)*((int*)p),(unsigned long)p);
bf38876a
LW
333#endif
334 nextf[bucket] = p->ov_next;
cf5c4ad8 335 OV_MAGIC(p, bucket) = MAGIC;
336#ifndef PACK_MALLOC
337 OV_INDEX(p) = bucket;
338#endif
c07a80fd 339#ifdef DEBUGGING_MSTATS
8d063cd8
LW
340 nmalloc[bucket]++;
341#endif
342#ifdef RCHECK
343 /*
344 * Record allocated size of block and
345 * bound space with magic numbers.
346 */
347 if (nbytes <= 0x10000)
348 p->ov_size = nbytes - 1;
349 p->ov_rmagic = RMAGIC;
350 *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
351#endif
cf5c4ad8 352 return ((Malloc_t)(p + CHUNK_SHIFT));
8d063cd8
LW
353}
354
355/*
356 * Allocate more memory to the indicated bucket.
357 */
a0d0e21e 358static void
8d063cd8 359morecore(bucket)
a687059c 360 register int bucket;
8d063cd8
LW
361{
362 register union overhead *op;
363 register int rnu; /* 2^rnu bytes will be requested */
364 register int nblks; /* become nblks blocks of the desired size */
ee0007ab 365 register MEM_SIZE siz;
cf5c4ad8 366 int slack = 0;
8d063cd8
LW
367
368 if (nextf[bucket])
369 return;
55497cff 370 if (bucket == (sizeof(MEM_SIZE)*8 - 3)) {
371 croak("Allocation too large");
372 }
8d063cd8
LW
373 /*
374 * Insure memory is allocated
375 * on a page boundary. Should
376 * make getpageize call?
377 */
ee0007ab 378#ifndef atarist /* on the atari we dont have to worry about this */
8d063cd8 379 op = (union overhead *)sbrk(0);
cf5c4ad8 380# ifndef I286
381# ifdef PACK_MALLOC
382 if ((int)op & 0x7ff)
383 (void)sbrk(slack = 2048 - ((int)op & 0x7ff));
384# else
8d063cd8 385 if ((int)op & 0x3ff)
cf5c4ad8 386 (void)sbrk(slack = 1024 - ((int)op & 0x3ff));
387# endif
388# if defined(DEBUGGING_MSTATS) && defined(PACK_MALLOC)
389 sbrk_slack += slack;
390# endif
391# else
a687059c 392 /* The sbrk(0) call on the I286 always returns the next segment */
cf5c4ad8 393# endif
ee0007ab 394#endif /* atarist */
a687059c 395
ee0007ab 396#if !(defined(I286) || defined(atarist))
8d063cd8
LW
397 /* take 2k unless the block is bigger than that */
398 rnu = (bucket <= 8) ? 11 : bucket + 3;
a687059c
LW
399#else
400 /* take 16k unless the block is bigger than that
ee0007ab 401 (80286s like large segments!), probably good on the atari too */
a687059c
LW
402 rnu = (bucket <= 11) ? 14 : bucket + 3;
403#endif
8d063cd8 404 nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */
cf5c4ad8 405 /* if (rnu < bucket)
406 rnu = bucket; Why anyone needs this? */
55497cff 407#ifdef TWO_POT_OPTIMIZE
408 op = (union overhead *)sbrk((1L << rnu)
409 + ( bucket >= (FIRST_BIG_TWO_POT - 3)
410 ? PERL_PAGESIZE : 0));
411#else
ee0007ab 412 op = (union overhead *)sbrk(1L << rnu);
55497cff 413#endif
8d063cd8 414 /* no more room! */
55497cff 415 if ((int)op == -1 &&
416 (int)(op = (union overhead *)emergency_sbrk(size)) == -1)
8d063cd8
LW
417 return;
418 /*
419 * Round up to minimum allocation size boundary
420 * and deduct from block count to reflect.
421 */
a687059c 422#ifndef I286
cf5c4ad8 423# ifdef PACK_MALLOC
424 if ((int)op & 0x7ff)
425 croak("panic: Off-page sbrk");
426# endif
8d063cd8 427 if ((int)op & 7) {
ee0007ab 428 op = (union overhead *)(((MEM_SIZE)op + 8) &~ 7);
8d063cd8
LW
429 nblks--;
430 }
a687059c
LW
431#else
432 /* Again, this should always be ok on an 80286 */
433#endif
8d063cd8
LW
434 /*
435 * Add new memory allocated to that on
436 * free list for this hash bucket.
437 */
8d063cd8 438 siz = 1 << (bucket + 3);
cf5c4ad8 439#ifdef PACK_MALLOC
440 *(u_char*)op = bucket; /* Fill index. */
441 if (bucket <= MAX_PACKED - 3) {
442 op = (union overhead *) ((char*)op + blk_shift[bucket]);
443 nblks = n_blks[bucket];
444# ifdef DEBUGGING_MSTATS
445 start_slack += blk_shift[bucket];
446# endif
447 } else if (bucket <= 11 - 1 - 3) {
448 op = (union overhead *) ((char*)op + blk_shift[bucket]);
449 /* nblks = n_blks[bucket]; */
450 siz -= sizeof(union overhead);
451 } else op++; /* One chunk per block. */
452#endif /* !PACK_MALLOC */
453 nextf[bucket] = op;
8d063cd8
LW
454 while (--nblks > 0) {
455 op->ov_next = (union overhead *)((caddr_t)op + siz);
456 op = (union overhead *)((caddr_t)op + siz);
457 }
8595d6f1 458 /* Not all sbrks return zeroed memory.*/
cf5c4ad8 459 op->ov_next = (union overhead *)NULL;
cf5c4ad8 460#ifdef PACK_MALLOC
461 if (bucket == 7 - 3) { /* Special case, explanation is above. */
462 union overhead *n_op = nextf[7 - 3]->ov_next;
463 nextf[7 - 3] = (union overhead *)((caddr_t)nextf[7 - 3]
464 - sizeof(union overhead));
465 nextf[7 - 3]->ov_next = n_op;
466 }
467#endif /* !PACK_MALLOC */
8d063cd8
LW
468}
469
94b6baf5 470Free_t
352d5a3a 471free(mp)
2304df62 472 Malloc_t mp;
8d063cd8 473{
ee0007ab 474 register MEM_SIZE size;
8d063cd8 475 register union overhead *op;
352d5a3a 476 char *cp = (char*)mp;
cf5c4ad8 477#ifdef PACK_MALLOC
478 u_char bucket;
479#endif
8d063cd8 480
55497cff 481#ifdef PERL_CORE
760ac839 482 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",(unsigned long)cp,an++));
55497cff 483#endif /* PERL_CORE */
45d8adaa 484
cf5c4ad8 485 if (cp == NULL)
486 return;
487 op = (union overhead *)((caddr_t)cp
488 - sizeof (union overhead) * CHUNK_SHIFT);
489#ifdef PACK_MALLOC
490 bucket = OV_INDEX(op);
491#endif
760ac839 492#ifdef DEBUGGING
cf5c4ad8 493 ASSERT(OV_MAGIC(op, bucket) == MAGIC); /* make sure it was in use */
8d063cd8 494#else
cf5c4ad8 495 if (OV_MAGIC(op, bucket) != MAGIC) {
496 static bad_free_warn = -1;
497 if (bad_free_warn == -1) {
498 char *pbf = getenv("PERL_BADFREE");
499 bad_free_warn = (pbf) ? atoi(pbf) : 1;
500 }
501 if (!bad_free_warn)
502 return;
8990e307 503#ifdef RCHECK
a687059c 504 warn("%s free() ignored",
8990e307
LW
505 op->ov_rmagic == RMAGIC - 1 ? "Duplicate" : "Bad");
506#else
507 warn("Bad free() ignored");
508#endif
8d063cd8 509 return; /* sanity */
378cc40b 510 }
8d063cd8
LW
511#endif
512#ifdef RCHECK
513 ASSERT(op->ov_rmagic == RMAGIC);
cf5c4ad8 514 if (OV_INDEX(op) <= 13)
8d063cd8 515 ASSERT(*(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) == RMAGIC);
8990e307 516 op->ov_rmagic = RMAGIC - 1;
8d063cd8 517#endif
cf5c4ad8 518 ASSERT(OV_INDEX(op) < NBUCKETS);
519 size = OV_INDEX(op);
8d063cd8
LW
520 op->ov_next = nextf[size];
521 nextf[size] = op;
c07a80fd 522#ifdef DEBUGGING_MSTATS
8d063cd8
LW
523 nmalloc[size]--;
524#endif
525}
526
527/*
528 * When a program attempts "storage compaction" as mentioned in the
529 * old malloc man page, it realloc's an already freed block. Usually
530 * this is the last block it freed; occasionally it might be farther
531 * back. We have to search all the free lists for the block in order
532 * to determine its bucket: 1st we make one pass thru the lists
533 * checking only the first block in each; if that fails we search
378cc40b 534 * ``reall_srchlen'' blocks in each list for a match (the variable
8d063cd8
LW
535 * is extern so the caller can modify it). If that fails we just copy
536 * however many bytes was given to realloc() and hope it's not huge.
537 */
378cc40b 538int reall_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
8d063cd8 539
2304df62 540Malloc_t
352d5a3a 541realloc(mp, nbytes)
2304df62 542 Malloc_t mp;
ee0007ab 543 MEM_SIZE nbytes;
8d063cd8 544{
ee0007ab 545 register MEM_SIZE onb;
8d063cd8
LW
546 union overhead *op;
547 char *res;
548 register int i;
549 int was_alloced = 0;
352d5a3a 550 char *cp = (char*)mp;
8d063cd8 551
55497cff 552#ifdef PERL_CORE
45d8adaa 553#ifdef DEBUGGING
ee0007ab 554 MEM_SIZE size = nbytes;
45d8adaa
LW
555#endif
556
55497cff 557#ifdef HAS_64K_LIMIT
45d8adaa 558 if (nbytes > 0xffff) {
760ac839 559 PerlIO_printf(PerlIO_stderr(), "Reallocation too large: %lx\n", size);
79072805 560 my_exit(1);
45d8adaa 561 }
55497cff 562#endif /* HAS_64K_LIMIT */
45d8adaa 563 if (!cp)
ee0007ab 564 return malloc(nbytes);
45d8adaa
LW
565#ifdef DEBUGGING
566 if ((long)nbytes < 0)
463ee0b2 567 croak("panic: realloc");
45d8adaa 568#endif
55497cff 569#endif /* PERL_CORE */
45d8adaa 570
cf5c4ad8 571 op = (union overhead *)((caddr_t)cp
572 - sizeof (union overhead) * CHUNK_SHIFT);
573 i = OV_INDEX(op);
574 if (OV_MAGIC(op, i) == MAGIC) {
55497cff 575 was_alloced = 1;
8d063cd8
LW
576 } else {
577 /*
578 * Already free, doing "compaction".
579 *
580 * Search for the old block of memory on the
581 * free list. First, check the most common
582 * case (last element free'd), then (this failing)
378cc40b 583 * the last ``reall_srchlen'' items free'd.
8d063cd8
LW
584 * If all lookups fail, then assume the size of
585 * the memory block being realloc'd is the
586 * smallest possible.
587 */
588 if ((i = findbucket(op, 1)) < 0 &&
378cc40b 589 (i = findbucket(op, reall_srchlen)) < 0)
8d063cd8
LW
590 i = 0;
591 }
cf5c4ad8 592 onb = (1L << (i + 3)) -
593#ifdef PACK_MALLOC
594 (i <= (MAX_PACKED - 3) ? 0 : M_OVERHEAD)
595#else
596 M_OVERHEAD
597#endif
55497cff 598#ifdef TWO_POT_OPTIMIZE
599 + (i >= (FIRST_BIG_TWO_POT - 3) ? PERL_PAGESIZE : 0)
600#endif
cf5c4ad8 601 ;
55497cff 602 /*
603 * avoid the copy if same size block.
604 * We are not agressive with boundary cases. Note that it is
605 * possible for small number of cases give false negative if
606 * both new size and old one are in the bucket for
607 * FIRST_BIG_TWO_POT, but the new one is near the lower end.
608 */
8d063cd8 609 if (was_alloced &&
55497cff 610 nbytes <= onb && (nbytes > ( (onb >> 1) - M_OVERHEAD )
611#ifdef TWO_POT_OPTIMIZE
612 || (i == (FIRST_BIG_TWO_POT - 3)
613 && nbytes >= LAST_SMALL_BOUND )
614#endif
615 )) {
a687059c
LW
616#ifdef RCHECK
617 /*
618 * Record new allocated size of block and
619 * bound space with magic numbers.
620 */
cf5c4ad8 621 if (OV_INDEX(op) <= 13) {
a687059c
LW
622 /*
623 * Convert amount of memory requested into
624 * closest block size stored in hash buckets
625 * which satisfies request. Account for
626 * space used per block for accounting.
627 */
cf5c4ad8 628 nbytes += M_OVERHEAD;
a687059c
LW
629 nbytes = (nbytes + 3) &~ 3;
630 op->ov_size = nbytes - 1;
631 *((u_int *)((caddr_t)op + nbytes - RSLOP)) = RMAGIC;
632 }
633#endif
45d8adaa 634 res = cp;
a687059c 635 }
45d8adaa
LW
636 else {
637 if ((res = (char*)malloc(nbytes)) == NULL)
638 return (NULL);
639 if (cp != res) /* common optimization */
ee0007ab 640 Copy(cp, res, (MEM_SIZE)(nbytes<onb?nbytes:onb), char);
45d8adaa
LW
641 if (was_alloced)
642 free(cp);
643 }
644
55497cff 645#ifdef PERL_CORE
45d8adaa 646#ifdef DEBUGGING
a0d0e21e 647 if (debug & 128) {
760ac839
LW
648 PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05d) rfree\n",(unsigned long)res,an++);
649 PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05d) realloc %ld bytes\n",
a0d0e21e
LW
650 (unsigned long)res,an++,(long)size);
651 }
45d8adaa 652#endif
55497cff 653#endif /* PERL_CORE */
2304df62 654 return ((Malloc_t)res);
8d063cd8
LW
655}
656
657/*
658 * Search ``srchlen'' elements of each free list for a block whose
659 * header starts at ``freep''. If srchlen is -1 search the whole list.
660 * Return bucket number, or -1 if not found.
661 */
ee0007ab 662static int
8d063cd8
LW
663findbucket(freep, srchlen)
664 union overhead *freep;
665 int srchlen;
666{
667 register union overhead *p;
668 register int i, j;
669
670 for (i = 0; i < NBUCKETS; i++) {
671 j = 0;
672 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
673 if (p == freep)
674 return (i);
675 j++;
676 }
677 }
678 return (-1);
679}
680
cf5c4ad8 681Malloc_t
682calloc(elements, size)
683 register MEM_SIZE elements;
684 register MEM_SIZE size;
685{
686 long sz = elements * size;
687 Malloc_t p = malloc(sz);
688
689 if (p) {
690 memset((void*)p, 0, sz);
691 }
692 return p;
693}
694
c07a80fd 695#ifdef DEBUGGING_MSTATS
8d063cd8
LW
696/*
697 * mstats - print out statistics about malloc
698 *
699 * Prints two lines of numbers, one showing the length of the free list
700 * for each size category, the second showing the number of mallocs -
701 * frees for each size category.
702 */
ee0007ab 703void
c07a80fd 704dump_mstats(s)
8d063cd8
LW
705 char *s;
706{
707 register int i, j;
708 register union overhead *p;
c07a80fd 709 int topbucket=0, totfree=0, totused=0;
710 u_int nfree[NBUCKETS];
8d063cd8 711
c07a80fd 712 for (i=0; i < NBUCKETS; i++) {
8d063cd8
LW
713 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
714 ;
c07a80fd 715 nfree[i] = j;
716 totfree += nfree[i] * (1 << (i + 3));
8d063cd8 717 totused += nmalloc[i] * (1 << (i + 3));
c07a80fd 718 if (nfree[i] || nmalloc[i])
719 topbucket = i;
720 }
721 if (s)
760ac839 722 PerlIO_printf(PerlIO_stderr(), "Memory allocation statistics %s (buckets 8..%d)\n",
c07a80fd 723 s, (1 << (topbucket + 3)) );
760ac839 724 PerlIO_printf(PerlIO_stderr(), " %7d free: ", totfree);
c07a80fd 725 for (i=0; i <= topbucket; i++) {
760ac839 726 PerlIO_printf(PerlIO_stderr(), (i<5)?" %5d":" %3d", nfree[i]);
8d063cd8 727 }
760ac839 728 PerlIO_printf(PerlIO_stderr(), "\n %7d used: ", totused);
c07a80fd 729 for (i=0; i <= topbucket; i++) {
760ac839 730 PerlIO_printf(PerlIO_stderr(), (i<5)?" %5d":" %3d", nmalloc[i]);
c07a80fd 731 }
760ac839 732 PerlIO_printf(PerlIO_stderr(), "\n");
cf5c4ad8 733#ifdef PACK_MALLOC
734 if (sbrk_slack || start_slack) {
760ac839 735 PerlIO_printf(PerlIO_stderr(), "Odd ends: %7d bytes from sbrk(), %7d from malloc.\n",
cf5c4ad8 736 sbrk_slack, start_slack);
737 }
738#endif
c07a80fd 739}
740#else
741void
742dump_mstats(s)
743 char *s;
744{
8d063cd8
LW
745}
746#endif
a687059c 747#endif /* lint */
cf5c4ad8 748
749
750#ifdef USE_PERL_SBRK
751
760ac839
LW
752# ifdef NeXT
753# define PERL_SBRK_VIA_MALLOC
754# endif
755
756# ifdef PERL_SBRK_VIA_MALLOC
757# ifdef HIDEMYMALLOC
758# undef malloc
759# else
760# include "Error: -DPERL_SBRK_VIA_MALLOC requires -DHIDEMYMALLOC"
761# endif
cf5c4ad8 762
763/* it may seem schizophrenic to use perl's malloc and let it call system */
764/* malloc, the reason for that is only the 3.2 version of the OS that had */
765/* frequent core dumps within nxzonefreenolock. This sbrk routine put an */
766/* end to the cores */
767
760ac839 768# define SYSTEM_ALLOC(a) malloc(a)
cf5c4ad8 769
760ac839 770# endif /* PERL_SBRK_VIA_MALLOC */
cf5c4ad8 771
772static IV Perl_sbrk_oldchunk;
773static long Perl_sbrk_oldsize;
774
760ac839
LW
775# define PERLSBRK_32_K (1<<15)
776# define PERLSBRK_64_K (1<<16)
cf5c4ad8 777
778char *
779Perl_sbrk(size)
780int size;
781{
782 IV got;
783 int small, reqsize;
784
785 if (!size) return 0;
55497cff 786#ifdef PERL_CORE
cf5c4ad8 787 reqsize = size; /* just for the DEBUG_m statement */
788#endif
789 if (size <= Perl_sbrk_oldsize) {
790 got = Perl_sbrk_oldchunk;
791 Perl_sbrk_oldchunk += size;
792 Perl_sbrk_oldsize -= size;
793 } else {
794 if (size >= PERLSBRK_32_K) {
795 small = 0;
796 } else {
55497cff 797#ifndef PERL_CORE
cf5c4ad8 798 reqsize = size;
799#endif
800 size = PERLSBRK_64_K;
801 small = 1;
802 }
803 got = (IV)SYSTEM_ALLOC(size);
804 if (small) {
805 /* Chunk is small, register the rest for future allocs. */
806 Perl_sbrk_oldchunk = got + reqsize;
807 Perl_sbrk_oldsize = size - reqsize;
808 }
809 }
810
55497cff 811#ifdef PERL_CORE
760ac839 812 DEBUG_m(PerlIO_printf(PerlIO_stderr(), "sbrk malloc size %ld (reqsize %ld), left size %ld, give addr 0x%lx\n",
cf5c4ad8 813 size, reqsize, Perl_sbrk_oldsize, got));
814#endif
815
816 return (void *)got;
817}
818
819#endif /* ! defined USE_PERL_SBRK */