* binutils/testsuite: made modifications to testcases, etc., to allow
[deliverable/binutils-gdb.git] / binutils / gmalloc.c
1
2 /* gmalloc.c - THIS FILE IS AUTOMAGICALLY GENERATED SO DON'T EDIT IT. */
3
4 /* Single-file skeleton for GNU malloc.
5 Copyright 1989 Free Software Foundation
6 Written May 1989 by Mike Haertel.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 The author may be reached (Email) at the address mike@ai.mit.edu,
23 or (US mail) as Mike Haertel c/o Free Software Foundation. */
24
25 #define __ONEFILE
26
27 /* DO NOT DELETE THIS LINE -- ansidecl.h INSERTED HERE. */
28 /* Copyright (C) 1989 Free Software Foundation, Inc.
29 This file is part of the GNU C Library.
30
31 The GNU C Library is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 1, or (at your option)
34 any later version.
35
36 The GNU C Library is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
40
41 You should have received a copy of the GNU General Public License
42 along with the GNU C Library; see the file COPYING. If not, write to
43 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
44
45 /* ANSI and traditional C compatibility macros
46
47 ANSI C is assumed if __STDC__ is #defined.
48
49 Macros
50 PTR - Generic pointer type
51 LONG_DOUBLE - `long double' type
52 CONST - `const' keyword
53 VOLATILE - `volatile' keyword
54 SIGNED - `signed' keyword
55 PTRCONST - Generic const pointer (void *const)
56
57 EXFUN(name, prototype) - declare external function NAME
58 with prototype PROTOTYPE
59 DEFUN(name, arglist, args) - define function NAME with
60 args ARGLIST of types in ARGS
61 DEFUN_VOID(name) - define function NAME with no args
62 AND - argument separator for ARGS
63 NOARGS - null arglist
64 DOTS - `...' in args
65
66 For example:
67 extern int EXFUN(printf, (CONST char *format DOTS));
68 int DEFUN(fprintf, (stream, format),
69 FILE *stream AND CONST char *format DOTS) { ... }
70 void DEFUN_VOID(abort) { ... }
71 */
72
73 #ifndef _ANSIDECL_H
74
75 #define _ANSIDECL_H 1
76
77
78 /* Every source file includes this file,
79 so they will all get the switch for lint. */
80 /* LINTLIBRARY */
81
82
83 #ifdef __STDC__
84
85 #define PTR void *
86 #define PTRCONST void *CONST
87 #define LONG_DOUBLE long double
88
89 #define AND ,
90 #define NOARGS void
91 #define CONST const
92 #define VOLATILE volatile
93 #define SIGNED signed
94 #define DOTS , ...
95
96 #define EXFUN(name, proto) name proto
97 #define DEFUN(name, arglist, args) name(args)
98 #define DEFUN_VOID(name) name(NOARGS)
99
100 #else /* Not ANSI C. */
101
102 #define PTR char *
103 #define PTRCONST PTR
104 #define LONG_DOUBLE double
105
106 #define AND ;
107 #define NOARGS
108 #define CONST
109 #define VOLATILE
110 #define SIGNED
111 #define DOTS
112
113 #define EXFUN(name, proto) name()
114 #define DEFUN(name, arglist, args) name arglist args;
115 #define DEFUN_VOID(name) name()
116
117 #endif /* ANSI C. */
118
119
120 #endif /* ansidecl.h */
121
122 #ifdef __STDC__
123 #include <limits.h>
124 #else
125 /* DO NOT DELETE THIS LINE -- limits.h INSERTED HERE. */
126 /* Number of bits in a `char'. */
127 #define CHAR_BIT 8
128
129 /* No multibyte characters supported yet. */
130 #define MB_LEN_MAX 1
131
132 /* Minimum and maximum values a `signed char' can hold. */
133 #define SCHAR_MIN -128
134 #define SCHAR_MAX 127
135
136 /* Maximum value an `unsigned char' can hold. (Minimum is 0). */
137 #define UCHAR_MAX 255U
138
139 /* Minimum and maximum values a `char' can hold. */
140 #ifdef __CHAR_UNSIGNED__
141 #define CHAR_MIN 0
142 #define CHAR_MAX 255U
143 #else
144 #define CHAR_MIN -128
145 #define CHAR_MAX 127
146 #endif
147
148 /* Minimum and maximum values a `signed short int' can hold. */
149 #define SHRT_MIN -32768
150 #define SHRT_MAX 32767
151
152 /* Maximum value an `unsigned short int' can hold. (Minimum is 0). */
153 #define USHRT_MAX 65535U
154
155 /* Minimum and maximum values a `signed int' can hold. */
156 #define INT_MIN -2147483648
157 #define INT_MAX 2147483647
158
159 /* Maximum value an `unsigned int' can hold. (Minimum is 0). */
160 #define UINT_MAX 4294967295U
161
162 /* Minimum and maximum values a `signed long int' can hold.
163 (Same as `int'). */
164 #define LONG_MIN (-LONG_MAX-1)
165 #define LONG_MAX 2147483647
166
167 /* Maximum value an `unsigned long int' can hold. (Minimum is 0). */
168 #define ULONG_MAX 4294967295U
169 #endif
170
171 #ifdef __STDC__
172 #include <stddef.h>
173 #else
174 /* DO NOT DELETE THIS LINE -- stddef.h INSERTED HERE. */
175 #ifndef _STDDEF_H
176 #define _STDDEF_H
177
178 /* Signed type of difference of two pointers. */
179
180 typedef long ptrdiff_t;
181
182 /* Unsigned type of `sizeof' something. */
183
184 #ifndef _SIZE_T /* in case <sys/types.h> has defined it. */
185 #define _SIZE_T
186 typedef unsigned long size_t;
187 #endif /* _SIZE_T */
188
189 /* A null pointer constant. */
190
191 #undef NULL /* in case <stdio.h> has defined it. */
192 #define NULL 0
193
194 /* Offset of member MEMBER in a struct of type TYPE. */
195
196 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
197
198 #endif /* _STDDEF_H */
199 #endif
200
201 /* DO NOT DELETE THIS LINE -- stdlib.h INSERTED HERE. */
202 /* Fake stdlib.h supplying the stuff needed by malloc. */
203
204 #ifndef __ONEFILE
205 #include <stddef.h>
206 #endif
207
208 extern void EXFUN(abort, (void));
209 extern void EXFUN(free, (PTR));
210 extern PTR EXFUN(malloc, (size_t));
211 extern PTR EXFUN(realloc, (PTR, size_t));
212
213 /* DO NOT DELETE THIS LINE -- string.h INSERTED HERE. */
214 /* Fake string.h supplying stuff used by malloc. */
215 #ifndef __ONEFILE
216 #include <stddef.h>
217 #endif
218
219 extern PTR EXFUN(memcpy, (PTR, PTR, size_t));
220 extern PTR EXFUN(memset, (PTR, int, size_t));
221 #define memmove memcpy
222
223 #define _MALLOC_INTERNAL
224 /* DO NOT DELETE THIS LINE -- malloc.h INSERTED HERE. */
225 /* Declarations for `malloc' and friends.
226 Copyright 1990 Free Software Foundation
227 Written May 1989 by Mike Haertel.
228
229 This program is free software; you can redistribute it and/or modify
230 it under the terms of the GNU General Public License as published by
231 the Free Software Foundation; either version 1, or (at your option)
232 any later version.
233
234 This program is distributed in the hope that it will be useful,
235 but WITHOUT ANY WARRANTY; without even the implied warranty of
236 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
237 GNU General Public License for more details.
238
239 You should have received a copy of the GNU General Public License
240 along with this program; if not, write to the Free Software
241 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
242
243 The author may be reached (Email) at the address mike@@ai.mit.edu,
244 or (US mail) as Mike Haertel c/o Free Software Foundation. */
245
246 #ifndef _MALLOC_H
247
248 #define _MALLOC_H 1
249
250 #ifndef __ONEFILE
251 #define __need_NULL
252 #define __need_size_t
253 #define __need_ptrdiff_t
254 #include <stddef.h>
255 #endif
256
257 #ifdef _MALLOC_INTERNAL
258
259 #ifndef __ONEFILE
260 #include <limits.h>
261 #endif
262
263 /* The allocator divides the heap into blocks of fixed size; large
264 requests receive one or more whole blocks, and small requests
265 receive a fragment of a block. Fragment sizes are powers of two,
266 and all fragments of a block are the same size. When all the
267 fragments in a block have been freed, the block itself is freed. */
268 #define INT_BIT (CHAR_BIT * sizeof(int))
269 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
270 #define BLOCKSIZE (1 << BLOCKLOG)
271 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
272
273 /* Determine the amount of memory spanned by the initial heap table
274 (not an absolute limit). */
275 #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
276
277 /* Number of contiguous free blocks allowed to build up at the end of
278 memory before they will be returned to the system. */
279 #define FINAL_FREE_BLOCKS 8
280
281 /* Where to start searching the free list when looking for new memory.
282 The two possible values are 0 and _heapindex. Starting at 0 seems
283 to reduce total memory usage, while starting at _heapindex seems to
284 run faster. */
285 #define MALLOC_SEARCH_START _heapindex
286
287 /* Data structure giving per-block information. */
288 typedef union
289 {
290 /* Heap information for a busy block. */
291 struct
292 {
293 /* Zero for a large block, or positive giving the
294 logarithm to the base two of the fragment size. */
295 int type;
296 union
297 {
298 struct
299 {
300 size_t nfree; /* Free fragments in a fragmented block. */
301 size_t first; /* First free fragment of the block. */
302 } frag;
303 /* Size (in blocks) of a large cluster. */
304 size_t size;
305 } info;
306 } busy;
307 /* Heap information for a free block (that may be the first of
308 a free cluster). */
309 struct
310 {
311 size_t size; /* Size (in blocks) of a free cluster. */
312 size_t next; /* Index of next free cluster. */
313 size_t prev; /* Index of previous free cluster. */
314 } free;
315 } malloc_info;
316
317 /* Pointer to first block of the heap. */
318 extern char *_heapbase;
319
320 /* Table indexed by block number giving per-block information. */
321 extern malloc_info *_heapinfo;
322
323 /* Address to block number and vice versa. */
324 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
325 #define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
326
327 /* Current search index for the heap table. */
328 extern size_t _heapindex;
329
330 /* Limit of valid info table indices. */
331 extern size_t _heaplimit;
332
333 /* Doubly linked lists of free fragments. */
334 struct list
335 {
336 struct list *next;
337 struct list *prev;
338 };
339
340 /* Free list headers for each fragment size. */
341 extern struct list _fraghead[];
342
343 /* Instrumentation. */
344 extern size_t _chunks_used;
345 extern size_t _bytes_used;
346 extern size_t _chunks_free;
347 extern size_t _bytes_free;
348
349 /* Internal version of free() used in morecore(). */
350 extern void EXFUN(__free, (PTR __ptr));
351
352 #endif /* _MALLOC_INTERNAL. */
353
354 /* Underlying allocation function; successive calls should
355 return contiguous pieces of memory. */
356 extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
357
358 /* Default value of previous. */
359 extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
360
361 /* Flag whether malloc has been called. */
362 extern int __malloc_initialized;
363
364 /* Hooks for debugging versions. */
365 extern void EXFUN((*__free_hook), (PTR __ptr));
366 extern PTR EXFUN((*__malloc_hook), (size_t __size));
367 extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
368
369 /* Activate a standard collection of debugging hooks. */
370 extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
371
372 /* Statistics available to the user. */
373 struct mstats
374 {
375 size_t bytes_total; /* Total size of the heap. */
376 size_t chunks_used; /* Chunks allocated by the user. */
377 size_t bytes_used; /* Byte total of user-allocated chunks. */
378 size_t chunks_free; /* Chunks in the free list. */
379 size_t bytes_free; /* Byte total of chunks in the free list. */
380 };
381
382 /* Pick up the current statistics. */
383 extern struct mstats EXFUN(mstats, (NOARGS));
384
385 #endif /* malloc.h */
386
387 /* DO NOT DELETE THIS LINE -- free.c INSERTED HERE. */
388 /* Free a block of memory allocated by `malloc'.
389 Copyright 1990 Free Software Foundation
390 Written May 1989 by Mike Haertel.
391
392 This program is free software; you can redistribute it and/or modify
393 it under the terms of the GNU General Public License as published by
394 the Free Software Foundation; either version 1, or (at your option)
395 any later version.
396
397 This program is distributed in the hope that it will be useful,
398 but WITHOUT ANY WARRANTY; without even the implied warranty of
399 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
400 GNU General Public License for more details.
401
402 You should have received a copy of the GNU General Public License
403 along with this program; if not, write to the Free Software
404 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
405
406 The author may be reached (Email) at the address mike@ai.mit.edu,
407 or (US mail) as Mike Haertel c/o Free Software Foundation. */
408
409 #ifndef __ONEFILE
410 #include "ansidecl.h"
411 #include <stddef.h>
412 #include <stdlib.h>
413
414 #define _MALLOC_INTERNAL
415 #include "malloc.h"
416 #endif /* __ONEFILE */
417
418 /* Debugging hook for free. */
419 void EXFUN((*__free_hook), (PTR __ptr));
420
421 /* Return memory to the heap. Like free() but don't call a __free_hook
422 if there is one. */
423 void
424 DEFUN(__free, (ptr), PTR ptr)
425 {
426 int type;
427 size_t block, blocks;
428 register size_t i;
429 struct list *prev, *next;
430
431 block = BLOCK(ptr);
432
433 type = _heapinfo[block].busy.type;
434 switch (type)
435 {
436 case 0:
437 /* Get as many statistics as early as we can. */
438 --_chunks_used;
439 _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
440 _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
441
442 /* Find the free cluster previous to this one in the free list.
443 Start searching at the last block referenced; this may benefit
444 programs with locality of allocation. */
445 i = _heapindex;
446 if (i > block)
447 while (i > block)
448 i = _heapinfo[i].free.prev;
449 else
450 {
451 do
452 i = _heapinfo[i].free.next;
453 while (i > 0 && i < block);
454 i = _heapinfo[i].free.prev;
455 }
456
457 /* Determine how to link this block into the free list. */
458 if (block == i + _heapinfo[i].free.size)
459 {
460 /* Coalesce this block with its predecessor. */
461 _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
462 block = i;
463 }
464 else
465 {
466 /* Really link this block back into the free list. */
467 _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
468 _heapinfo[block].free.next = _heapinfo[i].free.next;
469 _heapinfo[block].free.prev = i;
470 _heapinfo[i].free.next = block;
471 _heapinfo[_heapinfo[block].free.next].free.prev = block;
472 ++_chunks_free;
473 }
474
475 /* Now that the block is linked in, see if we can coalesce it
476 with its successor (by deleting its successor from the list
477 and adding in its size). */
478 if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
479 {
480 _heapinfo[block].free.size
481 += _heapinfo[_heapinfo[block].free.next].free.size;
482 _heapinfo[block].free.next
483 = _heapinfo[_heapinfo[block].free.next].free.next;
484 _heapinfo[_heapinfo[block].free.next].free.prev = block;
485 --_chunks_free;
486 }
487
488 /* Now see if we can return stuff to the system. */
489 blocks = _heapinfo[block].free.size;
490 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
491 && (*__morecore)(0) == ADDRESS(block + blocks))
492 {
493 register size_t bytes = blocks * BLOCKSIZE;
494 _heaplimit -= blocks;
495 (*__morecore)(- bytes);
496 _heapinfo[_heapinfo[block].free.prev].free.next
497 = _heapinfo[block].free.next;
498 _heapinfo[_heapinfo[block].free.next].free.prev
499 = _heapinfo[block].free.prev;
500 block = _heapinfo[block].free.prev;
501 --_chunks_free;
502 _bytes_free -= bytes;
503 }
504
505 /* Set the next search to begin at this block. */
506 _heapindex = block;
507 break;
508
509 default:
510 /* Do some of the statistics. */
511 --_chunks_used;
512 _bytes_used -= 1 << type;
513 ++_chunks_free;
514 _bytes_free += 1 << type;
515
516 /* Get the address of the first free fragment in this block. */
517 prev = (struct list *) ((char *) ADDRESS(block) +
518 (_heapinfo[block].busy.info.frag.first << type));
519
520 if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
521 {
522 /* If all fragments of this block are free, remove them
523 from the fragment list and free the whole block. */
524 next = prev;
525 for (i = 1; i < BLOCKSIZE >> type; ++i)
526 next = next->next;
527 prev->prev->next = next;
528 if (next != NULL)
529 next->prev = prev->prev;
530 _heapinfo[block].busy.type = 0;
531 _heapinfo[block].busy.info.size = 1;
532
533 /* Keep the statistics accurate. */
534 ++_chunks_used;
535 _bytes_used += BLOCKSIZE;
536 _chunks_free -= BLOCKSIZE >> type;
537 _bytes_free -= BLOCKSIZE;
538
539 free(ADDRESS(block));
540 }
541 else if (_heapinfo[block].busy.info.frag.nfree != 0)
542 {
543 /* If some fragments of this block are free, link this
544 fragment into the fragment list after the first free
545 fragment of this block. */
546 next = (struct list *) ptr;
547 next->next = prev->next;
548 next->prev = prev;
549 prev->next = next;
550 if (next->next != NULL)
551 next->next->prev = next;
552 ++_heapinfo[block].busy.info.frag.nfree;
553 }
554 else
555 {
556 /* No fragments of this block are free, so link this
557 fragment into the fragment list and announce that
558 it is the first free fragment of this block. */
559 prev = (struct list *) ptr;
560 _heapinfo[block].busy.info.frag.nfree = 1;
561 _heapinfo[block].busy.info.frag.first = (unsigned int)
562 (((char *) ptr - (char *) NULL) % BLOCKSIZE >> type);
563 prev->next = _fraghead[type].next;
564 prev->prev = &_fraghead[type];
565 prev->prev->next = prev;
566 if (prev->next != NULL)
567 prev->next->prev = prev;
568 }
569 break;
570 }
571 }
572
573 /* Return memory to the heap. */
574 void
575 DEFUN(free, (ptr), PTR ptr)
576 {
577 if (ptr == NULL)
578 return;
579
580 if (__free_hook != NULL)
581 (*__free_hook)(ptr);
582 else
583 __free (ptr);
584 }
585
586 /* DO NOT DELETE THIS LINE -- malloc.c INSERTED HERE. */
587 /* Memory allocator `malloc'.
588 Copyright 1990 Free Software Foundation
589 Written May 1989 by Mike Haertel.
590
591 This program is free software; you can redistribute it and/or modify
592 it under the terms of the GNU General Public License as published by
593 the Free Software Foundation; either version 1, or (at your option)
594 any later version.
595
596 This program is distributed in the hope that it will be useful,
597 but WITHOUT ANY WARRANTY; without even the implied warranty of
598 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
599 GNU General Public License for more details.
600
601 You should have received a copy of the GNU General Public License
602 along with this program; if not, write to the Free Software
603 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
604
605 The author may be reached (Email) at the address mike@ai.mit.edu,
606 or (US mail) as Mike Haertel c/o Free Software Foundation. */
607
608 #ifndef __ONEFILE
609 #include "ansidecl.h"
610 #include <stddef.h>
611 #include <stdlib.h>
612 #include <string.h>
613
614 #define _MALLOC_INTERNAL
615 #include "malloc.h"
616 #endif /* __ONEFILE */
617
618 /* How to really get more memory. */
619 PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
620
621 /* Debugging hook for `malloc'. */
622 PTR EXFUN((*__malloc_hook), (size_t __size));
623
624 /* Pointer to the base of the first block. */
625 char *_heapbase;
626
627 /* Block information table. Allocated with align/__free (not malloc/free). */
628 malloc_info *_heapinfo;
629
630 /* Number of info entries. */
631 static size_t heapsize;
632
633 /* Search index in the info table. */
634 size_t _heapindex;
635
636 /* Limit of valid info table indices. */
637 size_t _heaplimit;
638
639 /* Free lists for each fragment size. */
640 struct list _fraghead[BLOCKLOG];
641
642 /* Instrumentation. */
643 size_t _chunks_used;
644 size_t _bytes_used;
645 size_t _chunks_free;
646 size_t _bytes_free;
647
648 /* Are you experienced? */
649 int __malloc_initialized;
650
651 /* Aligned allocation. */
652 static PTR
653 DEFUN(align, (size), size_t size)
654 {
655 PTR result;
656 unsigned int adj;
657
658 result = (*__morecore)(size);
659 adj = (unsigned int) ((char *) result - (char *) NULL) % BLOCKSIZE;
660 if (adj != 0)
661 {
662 adj = BLOCKSIZE - adj;
663 (void) (*__morecore)(adj);
664 result = (char *) result + adj;
665 }
666 return result;
667 }
668
669 /* Set everything up and remember that we have. */
670 static int
671 DEFUN_VOID(initialize)
672 {
673 heapsize = HEAP / BLOCKSIZE;
674 _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info));
675 if (_heapinfo == NULL)
676 return 0;
677 memset(_heapinfo, 0, heapsize * sizeof(malloc_info));
678 _heapinfo[0].free.size = 0;
679 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
680 _heapindex = 0;
681 _heapbase = (char *) _heapinfo;
682 __malloc_initialized = 1;
683 return 1;
684 }
685
686 /* Get neatly aligned memory, initializing or
687 growing the heap info table as necessary. */
688 static PTR
689 DEFUN(morecore, (size), size_t size)
690 {
691 PTR result;
692 malloc_info *newinfo, *oldinfo;
693 size_t newsize;
694
695 result = align(size);
696 if (result == NULL)
697 return NULL;
698
699 /* Check if we need to grow the info table. */
700 if (BLOCK((char *) result + size) > heapsize)
701 {
702 newsize = heapsize;
703 while (BLOCK((char *) result + size) > newsize)
704 newsize *= 2;
705 newinfo = (malloc_info *) align(newsize * sizeof(malloc_info));
706 if (newinfo == NULL)
707 {
708 (*__morecore)(- size);
709 return NULL;
710 }
711 memset(newinfo, 0, newsize * sizeof(malloc_info));
712 memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info));
713 oldinfo = _heapinfo;
714 newinfo[BLOCK(oldinfo)].busy.type = 0;
715 newinfo[BLOCK(oldinfo)].busy.info.size
716 = BLOCKIFY(heapsize * sizeof(malloc_info));
717 _heapinfo = newinfo;
718 __free(oldinfo);
719 heapsize = newsize;
720 }
721
722 _heaplimit = BLOCK((char *) result + size);
723 return result;
724 }
725
726 /* Allocate memory from the heap. */
727 PTR
728 DEFUN(malloc, (size), size_t size)
729 {
730 PTR result;
731 size_t block, blocks, lastblocks, start;
732 register size_t i;
733 struct list *next;
734
735 if (size == 0)
736 return NULL;
737
738 if (__malloc_hook != NULL)
739 return (*__malloc_hook)(size);
740
741 if (!__malloc_initialized)
742 if (!initialize())
743 return NULL;
744
745 if (size < sizeof(struct list))
746 size = sizeof(struct list);
747
748 /* Determine the allocation policy based on the request size. */
749 if (size <= BLOCKSIZE / 2)
750 {
751 /* Small allocation to receive a fragment of a block.
752 Determine the logarithm to base two of the fragment size. */
753 register size_t log = 1;
754 --size;
755 while ((size /= 2) != 0)
756 ++log;
757
758 /* Look in the fragment lists for a
759 free fragment of the desired size. */
760 next = _fraghead[log].next;
761 if (next != NULL)
762 {
763 /* There are free fragments of this size.
764 Pop a fragment out of the fragment list and return it.
765 Update the block's nfree and first counters. */
766 result = (PTR) next;
767 next->prev->next = next->next;
768 if (next->next != NULL)
769 next->next->prev = next->prev;
770 block = BLOCK(result);
771 if (--_heapinfo[block].busy.info.frag.nfree != 0)
772 _heapinfo[block].busy.info.frag.first = (unsigned int)
773 (((char *) next->next - (char *) NULL) % BLOCKSIZE) >> log;
774
775 /* Update the statistics. */
776 ++_chunks_used;
777 _bytes_used += 1 << log;
778 --_chunks_free;
779 _bytes_free -= 1 << log;
780 }
781 else
782 {
783 /* No free fragments of the desired size, so get a new block
784 and break it into fragments, returning the first. */
785 result = malloc(BLOCKSIZE);
786 if (result == NULL)
787 return NULL;
788
789 /* Link all fragments but the first into the free list. */
790 for (i = 1; i < BLOCKSIZE >> log; ++i)
791 {
792 next = (struct list *) ((char *) result + (i << log));
793 next->next = _fraghead[log].next;
794 next->prev = &_fraghead[log];
795 next->prev->next = next;
796 if (next->next != NULL)
797 next->next->prev = next;
798 }
799
800 /* Initialize the nfree and first counters for this block. */
801 block = BLOCK(result);
802 _heapinfo[block].busy.type = log;
803 _heapinfo[block].busy.info.frag.nfree = i - 1;
804 _heapinfo[block].busy.info.frag.first = i - 1;
805
806 _chunks_free += (BLOCKSIZE >> log) - 1;
807 _bytes_free += BLOCKSIZE - (1 << log);
808 }
809 }
810 else
811 {
812 /* Large allocation to receive one or more blocks.
813 Search the free list in a circle starting at the last place visited.
814 If we loop completely around without finding a large enough
815 space we will have to get more memory from the system. */
816 blocks = BLOCKIFY(size);
817 start = block = MALLOC_SEARCH_START;
818 while (_heapinfo[block].free.size < blocks)
819 {
820 block = _heapinfo[block].free.next;
821 if (block == start)
822 {
823 /* Need to get more from the system. Check to see if
824 the new core will be contiguous with the final free
825 block; if so we don't need to get as much. */
826 block = _heapinfo[0].free.prev;
827 lastblocks = _heapinfo[block].free.size;
828 if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
829 (*__morecore)(0) == ADDRESS(block + lastblocks) &&
830 (morecore((blocks - lastblocks) * BLOCKSIZE)) != NULL)
831 {
832 _heapinfo[block].free.size = blocks;
833 _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
834 continue;
835 }
836 result = morecore(blocks * BLOCKSIZE);
837 if (result == NULL)
838 return NULL;
839 block = BLOCK(result);
840 _heapinfo[block].busy.type = 0;
841 _heapinfo[block].busy.info.size = blocks;
842 ++_chunks_used;
843 _bytes_used += blocks * BLOCKSIZE;
844 return result;
845 }
846 }
847
848 /* At this point we have found a suitable free list entry.
849 Figure out how to remove what we need from the list. */
850 result = ADDRESS(block);
851 if (_heapinfo[block].free.size > blocks)
852 {
853 /* The block we found has a bit left over,
854 so relink the tail end back into the free list. */
855 _heapinfo[block + blocks].free.size
856 = _heapinfo[block].free.size - blocks;
857 _heapinfo[block + blocks].free.next
858 = _heapinfo[block].free.next;
859 _heapinfo[block + blocks].free.prev
860 = _heapinfo[block].free.prev;
861 _heapinfo[_heapinfo[block].free.prev].free.next
862 = _heapinfo[_heapinfo[block].free.next].free.prev
863 = _heapindex = block + blocks;
864 }
865 else
866 {
867 /* The block exactly matches our requirements,
868 so just remove it from the list. */
869 _heapinfo[_heapinfo[block].free.next].free.prev
870 = _heapinfo[block].free.prev;
871 _heapinfo[_heapinfo[block].free.prev].free.next
872 = _heapindex = _heapinfo[block].free.next;
873 --_chunks_free;
874 }
875
876 _heapinfo[block].busy.type = 0;
877 _heapinfo[block].busy.info.size = blocks;
878 ++_chunks_used;
879 _bytes_used += blocks * BLOCKSIZE;
880 _bytes_free -= blocks * BLOCKSIZE;
881 }
882
883 return result;
884 }
885
886 /* DO NOT DELETE THIS LINE -- realloc.c INSERTED HERE. */
887 /* Change the size of a block allocated by `malloc'.
888 Copyright 1990 Free Software Foundation
889 Written May 1989 by Mike Haertel.
890
891 This program is free software; you can redistribute it and/or modify
892 it under the terms of the GNU General Public License as published by
893 the Free Software Foundation; either version 1, or (at your option)
894 any later version.
895
896 This program is distributed in the hope that it will be useful,
897 but WITHOUT ANY WARRANTY; without even the implied warranty of
898 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
899 GNU General Public License for more details.
900
901 You should have received a copy of the GNU General Public License
902 along with this program; if not, write to the Free Software
903 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
904
905 The author may be reached (Email) at the address mike@ai.mit.edu,
906 or (US mail) as Mike Haertel c/o Free Software Foundation. */
907
908 #ifndef __ONEFILE
909 #include "ansidecl.h"
910 #include <stdlib.h>
911 #include <string.h>
912
913 #define _MALLOC_INTERNAL
914 #include "malloc.h"
915 #endif /* __ONEFILE */
916
917 #define MIN(A, B) ((A) < (B) ? (A) : (B))
918
919 /* Debugging hook for realloc. */
920 PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
921
922 /* Resize the given region to the new size, returning a pointer
923 to the (possibly moved) region. This is optimized for speed;
924 some benchmarks seem to indicate that greater compactness is
925 achieved by unconditionally allocating and copying to a
926 new region. This module has incestuous knowledge of the
927 internals of both free and malloc. */
928 PTR
929 DEFUN(realloc, (ptr, size), PTR ptr AND size_t size)
930 {
931 PTR result;
932 int type;
933 size_t block, blocks, oldlimit;
934
935 if (size == 0)
936 {
937 free(ptr);
938 return NULL;
939 }
940 else if (ptr == NULL)
941 return malloc(size);
942
943 if (__realloc_hook != NULL)
944 return (*__realloc_hook)(ptr, size);
945
946 block = BLOCK(ptr);
947
948 type = _heapinfo[block].busy.type;
949 switch (type)
950 {
951 case 0:
952 /* Maybe reallocate a large block to a small fragment. */
953 if (size <= BLOCKSIZE / 2)
954 {
955 result = malloc(size);
956 if (result != NULL)
957 {
958 memcpy(result, ptr, size);
959 free(ptr);
960 return result;
961 }
962 }
963
964 /* The new size is a large allocation as well;
965 see if we can hold it in place. */
966 blocks = BLOCKIFY(size);
967 if (blocks < _heapinfo[block].busy.info.size)
968 {
969 /* The new size is smaller; return
970 excess memory to the free list. */
971 _heapinfo[block + blocks].busy.type = 0;
972 _heapinfo[block + blocks].busy.info.size
973 = _heapinfo[block].busy.info.size - blocks;
974 _heapinfo[block].busy.info.size = blocks;
975 free(ADDRESS(block + blocks));
976 result = ptr;
977 }
978 else if (blocks == _heapinfo[block].busy.info.size)
979 /* No size change necessary. */
980 result = ptr;
981 else
982 {
983 /* Won't fit, so allocate a new region that will.
984 Free the old region first in case there is sufficient
985 adjacent free space to grow without moving. */
986 blocks = _heapinfo[block].busy.info.size;
987 /* Prevent free from actually returning memory to the system. */
988 oldlimit = _heaplimit;
989 _heaplimit = 0;
990 free(ptr);
991 _heaplimit = oldlimit;
992 result = malloc(size);
993 if (result == NULL)
994 {
995 (void) malloc(blocks * BLOCKSIZE);
996 return NULL;
997 }
998 if (ptr != result)
999 memmove(result, ptr, blocks * BLOCKSIZE);
1000 }
1001 break;
1002
1003 default:
1004 /* Old size is a fragment; type is logarithm
1005 to base two of the fragment size. */
1006 if (size > 1 << (type - 1) && size <= 1 << type)
1007 /* The new size is the same kind of fragment. */
1008 result = ptr;
1009 else
1010 {
1011 /* The new size is different; allocate a new space,
1012 and copy the lesser of the new size and the old. */
1013 result = malloc(size);
1014 if (result == NULL)
1015 return NULL;
1016 memcpy(result, ptr, MIN(size, 1 << type));
1017 free(ptr);
1018 }
1019 break;
1020 }
1021
1022 return result;
1023 }
1024
1025 /* DO NOT DELETE THIS LINE -- unix.c INSERTED HERE. */
1026 /* unix.c - get more memory with a UNIX system call.
1027 Copyright 1990 Free Software Foundation
1028 Written May 1989 by Mike Haertel.
1029
1030 This program is free software; you can redistribute it and/or modify
1031 it under the terms of the GNU General Public License as published by
1032 the Free Software Foundation; either version 1, or (at your option)
1033 any later version.
1034
1035 This program is distributed in the hope that it will be useful,
1036 but WITHOUT ANY WARRANTY; without even the implied warranty of
1037 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1038 GNU General Public License for more details.
1039
1040 You should have received a copy of the GNU General Public License
1041 along with this program; if not, write to the Free Software
1042 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1043
1044 The author may be reached (Email) at the address mike@ai.mit.edu,
1045 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1046
1047 #ifndef __ONEFILE
1048 #include "ansidecl.h"
1049 #include <stddef.h>
1050
1051 #define _MALLOC_INTERNAL
1052 #include "malloc.h"
1053 #endif /* __ONEFILE */
1054
1055 extern PTR EXFUN(sbrk, (ptrdiff_t size));
1056
1057 PTR
1058 DEFUN(__default_morecore, (size), ptrdiff_t size)
1059 {
1060 PTR result;
1061
1062 result = sbrk(size);
1063 if (result == (PTR) -1)
1064 return NULL;
1065 return result;
1066 }
1067
1068 #define __getpagesize getpagesize
1069 /* DO NOT DELETE THIS LINE -- valloc.c INSERTED HERE. */
1070 /* Allocate memory on a page boundary.
1071 Copyright 1990 Free Software Foundation
1072 Written May 1989 by Mike Haertel.
1073
1074 This program is free software; you can redistribute it and/or modify
1075 it under the terms of the GNU General Public License as published by
1076 the Free Software Foundation; either version 1, or (at your option)
1077 any later version.
1078
1079 This program is distributed in the hope that it will be useful,
1080 but WITHOUT ANY WARRANTY; without even the implied warranty of
1081 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1082 GNU General Public License for more details.
1083
1084 You should have received a copy of the GNU General Public License
1085 along with this program; if not, write to the Free Software
1086 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1087
1088 The author may be reached (Email) at the address mike@ai.mit.edu,
1089 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1090
1091 #ifndef __ONEFILE
1092 #include "ansidecl.h"
1093 #include <stdlib.h>
1094 #endif /* __ONEFILE */
1095
1096 extern size_t EXFUN(__getpagesize, (NOARGS));
1097
1098 static size_t pagesize;
1099
1100 PTR
1101 DEFUN(valloc, (size), size_t size)
1102 {
1103 PTR result;
1104 unsigned int adj;
1105
1106 if (pagesize == 0)
1107 pagesize = __getpagesize();
1108
1109 result = malloc(size + pagesize);
1110 if (result == NULL)
1111 return NULL;
1112 adj = (unsigned int) ((char *) result - (char *) NULL) % pagesize;
1113 if (adj != 0)
1114 result = (char *) result + pagesize - adj;
1115 return result;
1116 }
This page took 0.06758 seconds and 4 git commands to generate.