fsf address update, but not in COPYING files
[deliverable/binutils-gdb.git] / binutils / gmalloc.c
CommitLineData
c074abee
DHW
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
943fbd5b 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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.
29This file is part of the GNU C Library.
30
31The GNU C Library is free software; you can redistribute it and/or modify
32it under the terms of the GNU General Public License as published by
33the Free Software Foundation; either version 1, or (at your option)
34any later version.
35
36The GNU C Library is distributed in the hope that it will be useful,
37but WITHOUT ANY WARRANTY; without even the implied warranty of
38MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39GNU General Public License for more details.
40
41You should have received a copy of the GNU General Public License
42along with the GNU C Library; see the file COPYING. If not, write to
943fbd5b 43the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
c074abee
DHW
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
180typedef 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
186typedef 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
208extern void EXFUN(abort, (void));
209extern void EXFUN(free, (PTR));
210extern PTR EXFUN(malloc, (size_t));
211extern 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
219extern PTR EXFUN(memcpy, (PTR, PTR, size_t));
220extern 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
943fbd5b 241 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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. */
288typedef 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. */
318extern char *_heapbase;
319
320/* Table indexed by block number giving per-block information. */
321extern 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. */
328extern size_t _heapindex;
329
330/* Limit of valid info table indices. */
331extern size_t _heaplimit;
332
333/* Doubly linked lists of free fragments. */
334struct list
335 {
336 struct list *next;
337 struct list *prev;
338 };
339
340/* Free list headers for each fragment size. */
341extern struct list _fraghead[];
342
343/* Instrumentation. */
344extern size_t _chunks_used;
345extern size_t _bytes_used;
346extern size_t _chunks_free;
347extern size_t _bytes_free;
348
349/* Internal version of free() used in morecore(). */
350extern void EXFUN(__free, (PTR __ptr));
351
352#endif /* _MALLOC_INTERNAL. */
353
354/* Underlying allocation function; successive calls should
355 return contiguous pieces of memory. */
356extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
357
358/* Default value of previous. */
359extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
360
361/* Flag whether malloc has been called. */
362extern int __malloc_initialized;
363
364/* Hooks for debugging versions. */
365extern void EXFUN((*__free_hook), (PTR __ptr));
366extern PTR EXFUN((*__malloc_hook), (size_t __size));
367extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
368
369/* Activate a standard collection of debugging hooks. */
370extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
371
372/* Statistics available to the user. */
373struct 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. */
383extern 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
943fbd5b 404 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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. */
419void 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. */
423void
424DEFUN(__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. */
574void
575DEFUN(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
943fbd5b 603 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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. */
619PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
620
621/* Debugging hook for `malloc'. */
622PTR EXFUN((*__malloc_hook), (size_t __size));
623
624/* Pointer to the base of the first block. */
625char *_heapbase;
626
627/* Block information table. Allocated with align/__free (not malloc/free). */
628malloc_info *_heapinfo;
629
630/* Number of info entries. */
631static size_t heapsize;
632
633/* Search index in the info table. */
634size_t _heapindex;
635
636/* Limit of valid info table indices. */
637size_t _heaplimit;
638
639/* Free lists for each fragment size. */
640struct list _fraghead[BLOCKLOG];
641
642/* Instrumentation. */
643size_t _chunks_used;
644size_t _bytes_used;
645size_t _chunks_free;
646size_t _bytes_free;
647
648/* Are you experienced? */
649int __malloc_initialized;
650
651/* Aligned allocation. */
652static PTR
653DEFUN(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. */
670static int
671DEFUN_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. */
688static PTR
689DEFUN(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. */
727PTR
728DEFUN(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
943fbd5b 903 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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. */
920PTR 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. */
928PTR
929DEFUN(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
943fbd5b 1042 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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
1055extern PTR EXFUN(sbrk, (ptrdiff_t size));
1056
1057PTR
1058DEFUN(__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
943fbd5b 1086 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c074abee
DHW
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
1096extern size_t EXFUN(__getpagesize, (NOARGS));
1097
1098static size_t pagesize;
1099
1100PTR
1101DEFUN(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.169941 seconds and 4 git commands to generate.