sun386 host/target/native separation
[deliverable/binutils-gdb.git] / gdb / gmalloc.c
CommitLineData
dd3b648e
RP
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
99a7de40
JG
8 The author may be reached (Email) at the address mike@ai.mit.edu,
9 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 10
99a7de40
JG
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2 of the License, or
14(at your option) any later version.
dd3b648e 15
99a7de40
JG
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
dd3b648e 20
99a7de40
JG
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
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
99a7de40 31This program is free software; you can redistribute it and/or modify
dd3b648e 32it under the terms of the GNU General Public License as published by
99a7de40
JG
33the Free Software Foundation; either version 2 of the License, or
34(at your option) any later version.
dd3b648e 35
99a7de40 36This program is distributed in the hope that it will be useful,
dd3b648e
RP
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
99a7de40
JG
42along with this program; if not, write to the Free Software
43Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
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
1ab3bf1b 208extern void EXFUN(abort, (NOARGS));
dd3b648e
RP
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
abefb1f1 219extern PTR EXFUN(memcpy, (PTR, CONST PTR, size_t));
dd3b648e
RP
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
99a7de40
JG
229 The author may be reached (Email) at the address mike@ai.mit.edu,
230 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 231
99a7de40
JG
232This program is free software; you can redistribute it and/or modify
233it under the terms of the GNU General Public License as published by
234the Free Software Foundation; either version 2 of the License, or
235(at your option) any later version.
dd3b648e 236
99a7de40
JG
237This program is distributed in the hope that it will be useful,
238but WITHOUT ANY WARRANTY; without even the implied warranty of
239MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
240GNU General Public License for more details.
dd3b648e 241
99a7de40
JG
242You should have received a copy of the GNU General Public License
243along with this program; if not, write to the Free Software
244Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
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)
1ab3bf1b 270#define BLOCKSIZE ((unsigned int) 1 << BLOCKLOG)
dd3b648e
RP
271#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
272
e59622b4
FF
273/* The difference between two pointers is a signed int. On machines where
274 the data addresses have the high bit set, we need to ensure that the
275 difference becomes an unsigned int when we are using the address as an
276 integral value. In addition, when using with the '%' operator, the
277 sign of the result is machine dependent for negative values, so force
278 it to be treated as an unsigned int. */
279
280#define ADDR2UINT(addr) ((unsigned int) ((char *) (addr) - (char *) NULL))
281#define RESIDUAL(addr) ((unsigned int) (ADDR2UINT (addr) % BLOCKSIZE))
282
dd3b648e
RP
283/* Determine the amount of memory spanned by the initial heap table
284 (not an absolute limit). */
285#define HEAP (INT_BIT > 16 ? 4194304 : 65536)
286
287/* Number of contiguous free blocks allowed to build up at the end of
288 memory before they will be returned to the system. */
289#define FINAL_FREE_BLOCKS 8
290
291/* Where to start searching the free list when looking for new memory.
292 The two possible values are 0 and _heapindex. Starting at 0 seems
293 to reduce total memory usage, while starting at _heapindex seems to
294 run faster. */
295#define MALLOC_SEARCH_START _heapindex
296
297/* Data structure giving per-block information. */
298typedef union
299 {
300 /* Heap information for a busy block. */
301 struct
302 {
303 /* Zero for a large block, or positive giving the
304 logarithm to the base two of the fragment size. */
305 int type;
306 union
307 {
308 struct
309 {
310 size_t nfree; /* Free fragments in a fragmented block. */
311 size_t first; /* First free fragment of the block. */
312 } frag;
313 /* Size (in blocks) of a large cluster. */
314 size_t size;
315 } info;
316 } busy;
317 /* Heap information for a free block (that may be the first of
318 a free cluster). */
319 struct
320 {
321 size_t size; /* Size (in blocks) of a free cluster. */
322 size_t next; /* Index of next free cluster. */
323 size_t prev; /* Index of previous free cluster. */
324 } free;
325 } malloc_info;
326
327/* Pointer to first block of the heap. */
328extern char *_heapbase;
329
330/* Table indexed by block number giving per-block information. */
331extern malloc_info *_heapinfo;
332
333/* Address to block number and vice versa. */
334#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
335#define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
336
337/* Current search index for the heap table. */
338extern size_t _heapindex;
339
340/* Limit of valid info table indices. */
341extern size_t _heaplimit;
342
343/* Doubly linked lists of free fragments. */
344struct list
345 {
346 struct list *next;
347 struct list *prev;
348 };
349
350/* Free list headers for each fragment size. */
351extern struct list _fraghead[];
352
353/* Instrumentation. */
354extern size_t _chunks_used;
355extern size_t _bytes_used;
356extern size_t _chunks_free;
357extern size_t _bytes_free;
358
359/* Internal version of free() used in morecore(). */
360extern void EXFUN(__free, (PTR __ptr));
361
362#endif /* _MALLOC_INTERNAL. */
363
364/* Underlying allocation function; successive calls should
365 return contiguous pieces of memory. */
366extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
367
368/* Default value of previous. */
369extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
370
371/* Flag whether malloc has been called. */
372extern int __malloc_initialized;
373
374/* Hooks for debugging versions. */
375extern void EXFUN((*__free_hook), (PTR __ptr));
376extern PTR EXFUN((*__malloc_hook), (size_t __size));
377extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
378
379/* Activate a standard collection of debugging hooks. */
1ab3bf1b 380extern void EXFUN(mcheck, (void EXFUN((*func), (NOARGS))));
dd3b648e
RP
381
382/* Statistics available to the user. */
383struct mstats
384 {
385 size_t bytes_total; /* Total size of the heap. */
386 size_t chunks_used; /* Chunks allocated by the user. */
387 size_t bytes_used; /* Byte total of user-allocated chunks. */
388 size_t chunks_free; /* Chunks in the free list. */
389 size_t bytes_free; /* Byte total of chunks in the free list. */
390 };
391
392/* Pick up the current statistics. */
393extern struct mstats EXFUN(mstats, (NOARGS));
394
395#endif /* malloc.h */
396
397/* DO NOT DELETE THIS LINE -- free.c INSERTED HERE. */
398/* Free a block of memory allocated by `malloc'.
399 Copyright 1990 Free Software Foundation
400 Written May 1989 by Mike Haertel.
401
99a7de40
JG
402 The author may be reached (Email) at the address mike@ai.mit.edu,
403 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 404
99a7de40
JG
405This program is free software; you can redistribute it and/or modify
406it under the terms of the GNU General Public License as published by
407the Free Software Foundation; either version 2 of the License, or
408(at your option) any later version.
dd3b648e 409
99a7de40
JG
410This program is distributed in the hope that it will be useful,
411but WITHOUT ANY WARRANTY; without even the implied warranty of
412MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
413GNU General Public License for more details.
dd3b648e 414
99a7de40
JG
415You should have received a copy of the GNU General Public License
416along with this program; if not, write to the Free Software
417Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
418
419#ifndef __ONEFILE
420#include "ansidecl.h"
421#include <stddef.h>
422#include <stdlib.h>
423
424#define _MALLOC_INTERNAL
425#include "malloc.h"
426#endif /* __ONEFILE */
427
428/* Debugging hook for free. */
429void EXFUN((*__free_hook), (PTR __ptr));
430
431/* Return memory to the heap. Like free() but don't call a __free_hook
432 if there is one. */
433void
434DEFUN(__free, (ptr), PTR ptr)
435{
436 int type;
437 size_t block, blocks;
438 register size_t i;
439 struct list *prev, *next;
440
441 block = BLOCK(ptr);
442
443 type = _heapinfo[block].busy.type;
444 switch (type)
445 {
446 case 0:
447 /* Get as many statistics as early as we can. */
448 --_chunks_used;
449 _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
450 _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
451
452 /* Find the free cluster previous to this one in the free list.
453 Start searching at the last block referenced; this may benefit
454 programs with locality of allocation. */
455 i = _heapindex;
456 if (i > block)
457 while (i > block)
458 i = _heapinfo[i].free.prev;
459 else
460 {
461 do
462 i = _heapinfo[i].free.next;
463 while (i > 0 && i < block);
464 i = _heapinfo[i].free.prev;
465 }
466
467 /* Determine how to link this block into the free list. */
468 if (block == i + _heapinfo[i].free.size)
469 {
470 /* Coalesce this block with its predecessor. */
471 _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
472 block = i;
473 }
474 else
475 {
476 /* Really link this block back into the free list. */
477 _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
478 _heapinfo[block].free.next = _heapinfo[i].free.next;
479 _heapinfo[block].free.prev = i;
480 _heapinfo[i].free.next = block;
481 _heapinfo[_heapinfo[block].free.next].free.prev = block;
482 ++_chunks_free;
483 }
484
485 /* Now that the block is linked in, see if we can coalesce it
486 with its successor (by deleting its successor from the list
487 and adding in its size). */
488 if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
489 {
490 _heapinfo[block].free.size
491 += _heapinfo[_heapinfo[block].free.next].free.size;
492 _heapinfo[block].free.next
493 = _heapinfo[_heapinfo[block].free.next].free.next;
494 _heapinfo[_heapinfo[block].free.next].free.prev = block;
495 --_chunks_free;
496 }
497
498 /* Now see if we can return stuff to the system. */
499 blocks = _heapinfo[block].free.size;
500 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
501 && (*__morecore)(0) == ADDRESS(block + blocks))
502 {
503 register size_t bytes = blocks * BLOCKSIZE;
504 _heaplimit -= blocks;
505 (*__morecore)(- bytes);
506 _heapinfo[_heapinfo[block].free.prev].free.next
507 = _heapinfo[block].free.next;
508 _heapinfo[_heapinfo[block].free.next].free.prev
509 = _heapinfo[block].free.prev;
510 block = _heapinfo[block].free.prev;
511 --_chunks_free;
512 _bytes_free -= bytes;
513 }
514
515 /* Set the next search to begin at this block. */
516 _heapindex = block;
517 break;
518
519 default:
520 /* Do some of the statistics. */
521 --_chunks_used;
522 _bytes_used -= 1 << type;
523 ++_chunks_free;
524 _bytes_free += 1 << type;
525
526 /* Get the address of the first free fragment in this block. */
527 prev = (struct list *) ((char *) ADDRESS(block) +
528 (_heapinfo[block].busy.info.frag.first << type));
529
530 if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
531 {
532 /* If all fragments of this block are free, remove them
533 from the fragment list and free the whole block. */
534 next = prev;
535 for (i = 1; i < BLOCKSIZE >> type; ++i)
536 next = next->next;
537 prev->prev->next = next;
538 if (next != NULL)
539 next->prev = prev->prev;
540 _heapinfo[block].busy.type = 0;
541 _heapinfo[block].busy.info.size = 1;
542
543 /* Keep the statistics accurate. */
544 ++_chunks_used;
545 _bytes_used += BLOCKSIZE;
546 _chunks_free -= BLOCKSIZE >> type;
547 _bytes_free -= BLOCKSIZE;
548
549 free(ADDRESS(block));
550 }
551 else if (_heapinfo[block].busy.info.frag.nfree != 0)
552 {
553 /* If some fragments of this block are free, link this
554 fragment into the fragment list after the first free
555 fragment of this block. */
556 next = (struct list *) ptr;
557 next->next = prev->next;
558 next->prev = prev;
559 prev->next = next;
560 if (next->next != NULL)
561 next->next->prev = next;
562 ++_heapinfo[block].busy.info.frag.nfree;
563 }
564 else
565 {
566 /* No fragments of this block are free, so link this
567 fragment into the fragment list and announce that
568 it is the first free fragment of this block. */
569 prev = (struct list *) ptr;
570 _heapinfo[block].busy.info.frag.nfree = 1;
e59622b4 571 _heapinfo[block].busy.info.frag.first = RESIDUAL (ptr) >> type;
dd3b648e
RP
572 prev->next = _fraghead[type].next;
573 prev->prev = &_fraghead[type];
574 prev->prev->next = prev;
575 if (prev->next != NULL)
576 prev->next->prev = prev;
577 }
578 break;
579 }
580}
581
582/* Return memory to the heap. */
583void
584DEFUN(free, (ptr), PTR ptr)
585{
586 if (ptr == NULL)
587 return;
588
589 if (__free_hook != NULL)
590 (*__free_hook)(ptr);
591 else
592 __free (ptr);
593}
594
595/* DO NOT DELETE THIS LINE -- malloc.c INSERTED HERE. */
596/* Memory allocator `malloc'.
597 Copyright 1990 Free Software Foundation
598 Written May 1989 by Mike Haertel.
599
99a7de40
JG
600 The author may be reached (Email) at the address mike@ai.mit.edu,
601 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 602
99a7de40
JG
603This program is free software; you can redistribute it and/or modify
604it under the terms of the GNU General Public License as published by
605the Free Software Foundation; either version 2 of the License, or
606(at your option) any later version.
dd3b648e 607
99a7de40
JG
608This program is distributed in the hope that it will be useful,
609but WITHOUT ANY WARRANTY; without even the implied warranty of
610MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
611GNU General Public License for more details.
dd3b648e 612
99a7de40
JG
613You should have received a copy of the GNU General Public License
614along with this program; if not, write to the Free Software
615Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
616
617#ifndef __ONEFILE
618#include "ansidecl.h"
619#include <stddef.h>
620#include <stdlib.h>
621#include <string.h>
622
623#define _MALLOC_INTERNAL
624#include "malloc.h"
625#endif /* __ONEFILE */
626
627/* How to really get more memory. */
628PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
629
630/* Debugging hook for `malloc'. */
631PTR EXFUN((*__malloc_hook), (size_t __size));
632
633/* Pointer to the base of the first block. */
634char *_heapbase;
635
636/* Block information table. Allocated with align/__free (not malloc/free). */
637malloc_info *_heapinfo;
638
639/* Number of info entries. */
640static size_t heapsize;
641
642/* Search index in the info table. */
643size_t _heapindex;
644
645/* Limit of valid info table indices. */
646size_t _heaplimit;
647
648/* Free lists for each fragment size. */
649struct list _fraghead[BLOCKLOG];
650
651/* Instrumentation. */
652size_t _chunks_used;
653size_t _bytes_used;
654size_t _chunks_free;
655size_t _bytes_free;
656
657/* Are you experienced? */
658int __malloc_initialized;
659
660/* Aligned allocation. */
661static PTR
662DEFUN(align, (size), size_t size)
663{
664 PTR result;
665 unsigned int adj;
666
667 result = (*__morecore)(size);
e59622b4 668 adj = RESIDUAL (result);
dd3b648e
RP
669 if (adj != 0)
670 {
671 adj = BLOCKSIZE - adj;
672 (void) (*__morecore)(adj);
673 result = (char *) result + adj;
674 }
675 return result;
676}
677
678/* Set everything up and remember that we have. */
679static int
680DEFUN_VOID(initialize)
681{
682 heapsize = HEAP / BLOCKSIZE;
683 _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info));
684 if (_heapinfo == NULL)
685 return 0;
686 memset(_heapinfo, 0, heapsize * sizeof(malloc_info));
687 _heapinfo[0].free.size = 0;
688 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
689 _heapindex = 0;
690 _heapbase = (char *) _heapinfo;
691 __malloc_initialized = 1;
692 return 1;
693}
694
695/* Get neatly aligned memory, initializing or
696 growing the heap info table as necessary. */
697static PTR
698DEFUN(morecore, (size), size_t size)
699{
700 PTR result;
701 malloc_info *newinfo, *oldinfo;
702 size_t newsize;
703
704 result = align(size);
705 if (result == NULL)
706 return NULL;
707
708 /* Check if we need to grow the info table. */
709 if (BLOCK((char *) result + size) > heapsize)
710 {
711 newsize = heapsize;
712 while (BLOCK((char *) result + size) > newsize)
713 newsize *= 2;
714 newinfo = (malloc_info *) align(newsize * sizeof(malloc_info));
715 if (newinfo == NULL)
716 {
717 (*__morecore)(- size);
718 return NULL;
719 }
720 memset(newinfo, 0, newsize * sizeof(malloc_info));
721 memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info));
722 oldinfo = _heapinfo;
723 newinfo[BLOCK(oldinfo)].busy.type = 0;
724 newinfo[BLOCK(oldinfo)].busy.info.size
725 = BLOCKIFY(heapsize * sizeof(malloc_info));
726 _heapinfo = newinfo;
727 __free(oldinfo);
728 heapsize = newsize;
729 }
730
731 _heaplimit = BLOCK((char *) result + size);
732 return result;
733}
734
735/* Allocate memory from the heap. */
736PTR
737DEFUN(malloc, (size), size_t size)
738{
739 PTR result;
740 size_t block, blocks, lastblocks, start;
741 register size_t i;
742 struct list *next;
743
744 if (size == 0)
745 return NULL;
746
747 if (__malloc_hook != NULL)
748 return (*__malloc_hook)(size);
749
750 if (!__malloc_initialized)
751 if (!initialize())
752 return NULL;
753
754 if (size < sizeof(struct list))
755 size = sizeof(struct list);
756
757 /* Determine the allocation policy based on the request size. */
758 if (size <= BLOCKSIZE / 2)
759 {
760 /* Small allocation to receive a fragment of a block.
761 Determine the logarithm to base two of the fragment size. */
762 register size_t log = 1;
763 --size;
764 while ((size /= 2) != 0)
765 ++log;
766
767 /* Look in the fragment lists for a
768 free fragment of the desired size. */
769 next = _fraghead[log].next;
770 if (next != NULL)
771 {
772 /* There are free fragments of this size.
773 Pop a fragment out of the fragment list and return it.
774 Update the block's nfree and first counters. */
775 result = (PTR) next;
776 next->prev->next = next->next;
777 if (next->next != NULL)
778 next->next->prev = next->prev;
779 block = BLOCK(result);
780 if (--_heapinfo[block].busy.info.frag.nfree != 0)
e59622b4
FF
781 _heapinfo[block].busy.info.frag.first =
782 RESIDUAL (next->next) >> log;
dd3b648e
RP
783
784 /* Update the statistics. */
785 ++_chunks_used;
786 _bytes_used += 1 << log;
787 --_chunks_free;
788 _bytes_free -= 1 << log;
789 }
790 else
791 {
792 /* No free fragments of the desired size, so get a new block
793 and break it into fragments, returning the first. */
794 result = malloc(BLOCKSIZE);
795 if (result == NULL)
796 return NULL;
797
798 /* Link all fragments but the first into the free list. */
799 for (i = 1; i < BLOCKSIZE >> log; ++i)
800 {
801 next = (struct list *) ((char *) result + (i << log));
802 next->next = _fraghead[log].next;
803 next->prev = &_fraghead[log];
804 next->prev->next = next;
805 if (next->next != NULL)
806 next->next->prev = next;
807 }
808
809 /* Initialize the nfree and first counters for this block. */
810 block = BLOCK(result);
811 _heapinfo[block].busy.type = log;
812 _heapinfo[block].busy.info.frag.nfree = i - 1;
813 _heapinfo[block].busy.info.frag.first = i - 1;
814
815 _chunks_free += (BLOCKSIZE >> log) - 1;
816 _bytes_free += BLOCKSIZE - (1 << log);
817 }
818 }
819 else
820 {
821 /* Large allocation to receive one or more blocks.
822 Search the free list in a circle starting at the last place visited.
823 If we loop completely around without finding a large enough
824 space we will have to get more memory from the system. */
825 blocks = BLOCKIFY(size);
826 start = block = MALLOC_SEARCH_START;
827 while (_heapinfo[block].free.size < blocks)
828 {
829 block = _heapinfo[block].free.next;
830 if (block == start)
831 {
832 /* Need to get more from the system. Check to see if
833 the new core will be contiguous with the final free
834 block; if so we don't need to get as much. */
835 block = _heapinfo[0].free.prev;
836 lastblocks = _heapinfo[block].free.size;
837 if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
838 (*__morecore)(0) == ADDRESS(block + lastblocks) &&
839 (morecore((blocks - lastblocks) * BLOCKSIZE)) != NULL)
840 {
841 _heapinfo[block].free.size = blocks;
842 _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
843 continue;
844 }
845 result = morecore(blocks * BLOCKSIZE);
846 if (result == NULL)
847 return NULL;
848 block = BLOCK(result);
849 _heapinfo[block].busy.type = 0;
850 _heapinfo[block].busy.info.size = blocks;
851 ++_chunks_used;
852 _bytes_used += blocks * BLOCKSIZE;
853 return result;
854 }
855 }
856
857 /* At this point we have found a suitable free list entry.
858 Figure out how to remove what we need from the list. */
859 result = ADDRESS(block);
860 if (_heapinfo[block].free.size > blocks)
861 {
862 /* The block we found has a bit left over,
863 so relink the tail end back into the free list. */
864 _heapinfo[block + blocks].free.size
865 = _heapinfo[block].free.size - blocks;
866 _heapinfo[block + blocks].free.next
867 = _heapinfo[block].free.next;
868 _heapinfo[block + blocks].free.prev
869 = _heapinfo[block].free.prev;
870 _heapinfo[_heapinfo[block].free.prev].free.next
871 = _heapinfo[_heapinfo[block].free.next].free.prev
872 = _heapindex = block + blocks;
873 }
874 else
875 {
876 /* The block exactly matches our requirements,
877 so just remove it from the list. */
878 _heapinfo[_heapinfo[block].free.next].free.prev
879 = _heapinfo[block].free.prev;
880 _heapinfo[_heapinfo[block].free.prev].free.next
881 = _heapindex = _heapinfo[block].free.next;
882 --_chunks_free;
883 }
884
885 _heapinfo[block].busy.type = 0;
886 _heapinfo[block].busy.info.size = blocks;
887 ++_chunks_used;
888 _bytes_used += blocks * BLOCKSIZE;
889 _bytes_free -= blocks * BLOCKSIZE;
890 }
891
892 return result;
893}
894
895/* DO NOT DELETE THIS LINE -- realloc.c INSERTED HERE. */
896/* Change the size of a block allocated by `malloc'.
897 Copyright 1990 Free Software Foundation
898 Written May 1989 by Mike Haertel.
899
99a7de40
JG
900 The author may be reached (Email) at the address mike@ai.mit.edu,
901 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 902
99a7de40
JG
903This program is free software; you can redistribute it and/or modify
904it under the terms of the GNU General Public License as published by
905the Free Software Foundation; either version 2 of the License, or
906(at your option) any later version.
dd3b648e 907
99a7de40
JG
908This program is distributed in the hope that it will be useful,
909but WITHOUT ANY WARRANTY; without even the implied warranty of
910MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
911GNU General Public License for more details.
dd3b648e 912
99a7de40
JG
913You should have received a copy of the GNU General Public License
914along with this program; if not, write to the Free Software
915Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
916
917#ifndef __ONEFILE
918#include "ansidecl.h"
919#include <stdlib.h>
920#include <string.h>
921
922#define _MALLOC_INTERNAL
923#include "malloc.h"
924#endif /* __ONEFILE */
925
926#define MIN(A, B) ((A) < (B) ? (A) : (B))
927
928/* Debugging hook for realloc. */
929PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
930
931/* Resize the given region to the new size, returning a pointer
932 to the (possibly moved) region. This is optimized for speed;
933 some benchmarks seem to indicate that greater compactness is
934 achieved by unconditionally allocating and copying to a
935 new region. This module has incestuous knowledge of the
936 internals of both free and malloc. */
937PTR
938DEFUN(realloc, (ptr, size), PTR ptr AND size_t size)
939{
940 PTR result;
941 int type;
942 size_t block, blocks, oldlimit;
943
944 if (size == 0)
945 {
946 free(ptr);
947 return NULL;
948 }
949 else if (ptr == NULL)
950 return malloc(size);
951
952 if (__realloc_hook != NULL)
953 return (*__realloc_hook)(ptr, size);
954
955 block = BLOCK(ptr);
956
957 type = _heapinfo[block].busy.type;
958 switch (type)
959 {
960 case 0:
961 /* Maybe reallocate a large block to a small fragment. */
962 if (size <= BLOCKSIZE / 2)
963 {
964 result = malloc(size);
965 if (result != NULL)
966 {
967 memcpy(result, ptr, size);
968 free(ptr);
969 return result;
970 }
971 }
972
973 /* The new size is a large allocation as well;
974 see if we can hold it in place. */
975 blocks = BLOCKIFY(size);
976 if (blocks < _heapinfo[block].busy.info.size)
977 {
978 /* The new size is smaller; return
979 excess memory to the free list. */
980 _heapinfo[block + blocks].busy.type = 0;
981 _heapinfo[block + blocks].busy.info.size
982 = _heapinfo[block].busy.info.size - blocks;
983 _heapinfo[block].busy.info.size = blocks;
984 free(ADDRESS(block + blocks));
985 result = ptr;
986 }
987 else if (blocks == _heapinfo[block].busy.info.size)
988 /* No size change necessary. */
989 result = ptr;
990 else
991 {
992 /* Won't fit, so allocate a new region that will.
993 Free the old region first in case there is sufficient
994 adjacent free space to grow without moving. */
995 blocks = _heapinfo[block].busy.info.size;
996 /* Prevent free from actually returning memory to the system. */
997 oldlimit = _heaplimit;
998 _heaplimit = 0;
999 free(ptr);
1000 _heaplimit = oldlimit;
1001 result = malloc(size);
1002 if (result == NULL)
1003 {
1004 (void) malloc(blocks * BLOCKSIZE);
1005 return NULL;
1006 }
1007 if (ptr != result)
1008 memmove(result, ptr, blocks * BLOCKSIZE);
1009 }
1010 break;
1011
1012 default:
1013 /* Old size is a fragment; type is logarithm
1014 to base two of the fragment size. */
1015 if (size > 1 << (type - 1) && size <= 1 << type)
1016 /* The new size is the same kind of fragment. */
1017 result = ptr;
1018 else
1019 {
1020 /* The new size is different; allocate a new space,
1021 and copy the lesser of the new size and the old. */
1022 result = malloc(size);
1023 if (result == NULL)
1024 return NULL;
1025 memcpy(result, ptr, MIN(size, 1 << type));
1026 free(ptr);
1027 }
1028 break;
1029 }
1030
1031 return result;
1032}
1033
1034/* DO NOT DELETE THIS LINE -- unix.c INSERTED HERE. */
1035/* unix.c - get more memory with a UNIX system call.
1036 Copyright 1990 Free Software Foundation
1037 Written May 1989 by Mike Haertel.
1038
99a7de40
JG
1039 The author may be reached (Email) at the address mike@ai.mit.edu,
1040 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 1041
99a7de40
JG
1042This program is free software; you can redistribute it and/or modify
1043it under the terms of the GNU General Public License as published by
1044the Free Software Foundation; either version 2 of the License, or
1045(at your option) any later version.
dd3b648e 1046
99a7de40
JG
1047This program is distributed in the hope that it will be useful,
1048but WITHOUT ANY WARRANTY; without even the implied warranty of
1049MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1050GNU General Public License for more details.
dd3b648e 1051
99a7de40
JG
1052You should have received a copy of the GNU General Public License
1053along with this program; if not, write to the Free Software
1054Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
1055
1056#ifndef __ONEFILE
1057#include "ansidecl.h"
1058#include <stddef.h>
1059
1060#define _MALLOC_INTERNAL
1061#include "malloc.h"
1062#endif /* __ONEFILE */
1063
1064extern PTR EXFUN(sbrk, (ptrdiff_t size));
1065
1066PTR
1067DEFUN(__default_morecore, (size), ptrdiff_t size)
1068{
1069 PTR result;
1070
1071 result = sbrk(size);
1072 if (result == (PTR) -1)
1073 return NULL;
1074 return result;
1075}
1076
1077#define __getpagesize getpagesize
1078/* DO NOT DELETE THIS LINE -- valloc.c INSERTED HERE. */
1079/* Allocate memory on a page boundary.
1080 Copyright 1990 Free Software Foundation
1081 Written May 1989 by Mike Haertel.
1082
99a7de40
JG
1083 The author may be reached (Email) at the address mike@ai.mit.edu,
1084 or (US mail) as Mike Haertel c/o Free Software Foundation.
dd3b648e 1085
99a7de40
JG
1086This program is free software; you can redistribute it and/or modify
1087it under the terms of the GNU General Public License as published by
1088the Free Software Foundation; either version 2 of the License, or
1089(at your option) any later version.
dd3b648e 1090
99a7de40
JG
1091This program is distributed in the hope that it will be useful,
1092but WITHOUT ANY WARRANTY; without even the implied warranty of
1093MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1094GNU General Public License for more details.
dd3b648e 1095
99a7de40
JG
1096You should have received a copy of the GNU General Public License
1097along with this program; if not, write to the Free Software
1098Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
1099
1100#ifndef __ONEFILE
1101#include "ansidecl.h"
1102#include <stdlib.h>
1103#endif /* __ONEFILE */
1104
127850e7
SEF
1105#if defined(M_UNIX)
1106/*
1107 * M_UNIX is defined by the SCO compilers, including the port of gcc.
1108 */
1109
2d3b4295
JK
1110/* On SunOS 4.1.1, <sys/param.h> typedefs size_t, which is bad since
1111 we typedef it above. Maybe it's better just to have people compile
1112 -Dgetpagesize()=4096. */
be11d111 1113/* Deal with page size. */
be11d111
JK
1114#ifndef HAVE_GETPAGESIZE
1115
1116#include <sys/param.h>
1117
1118#if !defined (PAGESIZE)
1119#ifdef EXEC_PAGESIZE
1120#define PAGESIZE EXEC_PAGESIZE
1121#else
1122#ifdef NBPG
1123#define PAGESIZE NBPG * CLSIZE
1124#ifndef CLSIZE
1125#define CLSIZE 1
1126#endif /* no CLSIZE */
1127#else /* no NBPG */
1128#define PAGESIZE NBPC
1129#endif /* no NBPG */
1130#endif /* no EXEC_PAGESIZE */
1131#endif /* no PAGESIZE */
1132
1133size_t
1134DEFUN_VOID(__getpagesize)
1135{
1136 return PAGESIZE;
1137}
1138#endif /* not HAVE_GETPAGESIZE */
127850e7 1139#endif /* M_UNIX */
be11d111 1140
dd3b648e
RP
1141extern size_t EXFUN(__getpagesize, (NOARGS));
1142
1143static size_t pagesize;
1144
1145PTR
1146DEFUN(valloc, (size), size_t size)
1147{
1148 PTR result;
1149 unsigned int adj;
1150
1151 if (pagesize == 0)
1152 pagesize = __getpagesize();
1153
1154 result = malloc(size + pagesize);
1155 if (result == NULL)
1156 return NULL;
1d0709e2 1157 adj = (unsigned int) ((unsigned int)((char *) result - (char *) NULL)) % pagesize;
dd3b648e
RP
1158 if (adj != 0)
1159 result = (char *) result + pagesize - adj;
1160 return result;
1161}
This page took 0.108007 seconds and 4 git commands to generate.