1 /* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */
3 #define _MALLOC_INTERNAL
5 /* The malloc headers and source files from the C library follow here. */
7 /* Declarations for `malloc' and friends.
8 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
9 Written May 1989 by Mike Haertel.
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
21 You should have received a copy of the GNU Library General Public
22 License along with this library; see the file COPYING.LIB. If
23 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
24 Cambridge, MA 02139, USA.
26 The author may be reached (Email) at the address mike@ai.mit.edu,
27 or (US mail) as Mike Haertel c/o Free Software Foundation. */
38 #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
40 #define __P(args) args
44 #define __ptr_t void *
45 #else /* Not C++ or ANSI C. */
51 #define __ptr_t char *
52 #endif /* C++ or ANSI C. */
61 #ifdef VMS /* The following are defined in stdio.h, but we need it NOW!
62 But do NOT do it with defines here, for then, VAX C is going
63 to barf when it gets to stdio.h and the typedefs in there! */
64 typedef unsigned int size_t;
65 typedef int ptrdiff_t;
68 #define size_t unsigned int
75 /* Allocate SIZE bytes of memory. */
76 extern __ptr_t malloc
__P ((size_t __size
));
77 /* Re-allocate the previously allocated block
78 in __ptr_t, making the new block SIZE bytes long. */
79 extern __ptr_t realloc
__P ((__ptr_t __ptr
, size_t __size
));
80 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
81 extern __ptr_t calloc
__P ((size_t __nmemb
, size_t __size
));
82 /* Free a block allocated by `malloc', `realloc' or `calloc'. */
83 extern void free
__P ((__ptr_t __ptr
));
85 /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
86 extern __ptr_t memalign
__P ((size_t __alignment
, size_t __size
));
88 /* Allocate SIZE bytes on a page boundary. */
89 extern __ptr_t valloc
__P ((size_t __size
));
92 /* VMS hooks to deal with two heaps */
93 /* Allocate SIZE bytes of memory. */
94 extern __ptr_t __vms_malloc
__P ((size_t __size
));
95 /* Re-allocate the previously allocated block
96 in __ptr_t, making the new block SIZE bytes long. */
97 extern __ptr_t __vms_realloc
__P ((__ptr_t __ptr
, size_t __size
));
98 /* Free a block allocated by `malloc', `realloc' or `calloc'. */
99 extern void __vms_free
__P ((__ptr_t __ptr
));
102 #ifdef _MALLOC_INTERNAL
104 #include <stdio.h> /* Harmless, gets __GNU_LIBRARY__ defined. */
106 #if defined(HAVE_CONFIG_H) || defined(emacs)
110 #if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) || defined(USG)
114 #define memset(s, zero, n) bzero ((s), (n))
117 #define memcpy(d, s, n) bcopy ((s), (d), (n))
120 #define memmove(d, s, n) bcopy ((s), (d), (n))
125 #if defined(__GNU_LIBRARY__) || defined(__STDC__)
131 /* The allocator divides the heap into blocks of fixed size; large
132 requests receive one or more whole blocks, and small requests
133 receive a fragment of a block. Fragment sizes are powers of two,
134 and all fragments of a block are the same size. When all the
135 fragments in a block have been freed, the block itself is freed. */
136 #define INT_BIT (CHAR_BIT * sizeof(int))
140 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
142 #define BLOCKSIZE (1 << BLOCKLOG)
143 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
145 /* Determine the amount of memory spanned by the initial heap table
146 (not an absolute limit). */
147 #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
149 /* Number of contiguous free blocks allowed to build up at the end of
150 memory before they will be returned to the system. */
151 #define FINAL_FREE_BLOCKS 8
153 /* Data structure giving per-block information. */
156 /* Heap information for a busy block. */
159 /* Zero for a large block, or positive giving the
160 logarithm to the base two of the fragment size. */
166 size_t nfree
; /* Free fragments in a fragmented block. */
167 size_t first
; /* First free fragment of the block. */
169 /* Size (in blocks) of a large cluster. */
173 /* Heap information for a free block
174 (that may be the first of a free cluster). */
177 size_t size
; /* Size (in blocks) of a free cluster. */
178 size_t next
; /* Index of next free cluster. */
179 size_t prev
; /* Index of previous free cluster. */
183 /* Pointer to first block of the heap. */
184 extern char *_heapbase
;
186 /* Table indexed by block number giving per-block information. */
187 extern malloc_info
*_heapinfo
;
189 /* Address to block number and vice versa. */
190 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
191 #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
193 /* Current search index for the heap table. */
194 extern size_t _heapindex
;
196 /* Limit of valid info table indices. */
197 extern size_t _heaplimit
;
199 /* Doubly linked lists of free fragments. */
206 /* Free list headers for each fragment size. */
207 extern struct list _fraghead
[];
209 /* List of blocks allocated with `memalign' (or `valloc'). */
212 struct alignlist
*next
;
213 __ptr_t aligned
; /* The address that memaligned returned. */
214 __ptr_t exact
; /* The address that malloc returned. */
216 extern struct alignlist
*_aligned_blocks
;
218 /* Instrumentation. */
219 extern size_t _chunks_used
;
220 extern size_t _bytes_used
;
221 extern size_t _chunks_free
;
222 extern size_t _bytes_free
;
224 /* Internal version of `free' used in `morecore' (malloc.c). */
225 extern void _free_internal
__P ((__ptr_t __ptr
));
227 #endif /* _MALLOC_INTERNAL. */
229 /* Underlying allocation function; successive calls should
230 return contiguous pieces of memory. */
231 /* It does NOT always return contiguous pieces of memory on VMS. */
232 extern __ptr_t (*__morecore
) __P ((ptrdiff_t __size
));
234 /* Underlying deallocation function. It accepts both a pointer and
235 a size to back up. It is implementation dependent what is really
237 extern __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
, ptrdiff_t __size
));
239 /* Default value of `__morecore'. */
240 extern __ptr_t __default_morecore
__P ((ptrdiff_t __size
));
242 /* Default value of `__lesscore'. */
243 extern __ptr_t __default_lesscore
__P ((__ptr_t __ptr
, ptrdiff_t __size
));
246 /* Default value of `__morecore'. */
247 extern __ptr_t __vms_morecore
__P ((ptrdiff_t __size
));
249 /* Default value of `__lesscore'. */
250 extern __ptr_t __vms_lesscore
__P ((__ptr_t __ptr
, ptrdiff_t __size
));
253 /* If not NULL, this function is called after each time
254 `__morecore' is called to increase the data size. */
255 extern void (*__after_morecore_hook
) __P ((void));
257 /* If not NULL, this function is called after each time
258 `__lesscore' is called to increase the data size. */
259 extern void (*__after_lesscore_hook
) __P ((void));
261 /* Nonzero if `malloc' has been called and done its initialization. */
262 extern int __malloc_initialized
;
264 /* Hooks for debugging versions. */
265 extern void (*__free_hook
) __P ((__ptr_t __ptr
));
266 extern __ptr_t (*__malloc_hook
) __P ((size_t __size
));
267 extern __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
));
269 /* Activate a standard collection of debugging hooks. */
270 extern int mcheck
__P ((void (*__func
) __P ((void))));
272 /* Activate a standard collection of tracing hooks. */
273 extern void mtrace
__P ((void));
275 /* Statistics available to the user. */
278 size_t bytes_total
; /* Total size of the heap. */
279 size_t chunks_used
; /* Chunks allocated by the user. */
280 size_t bytes_used
; /* Byte total of user-allocated chunks. */
281 size_t chunks_free
; /* Chunks in the free list. */
282 size_t bytes_free
; /* Byte total of chunks in the free list. */
285 /* Pick up the current statistics. */
286 extern struct mstats mstats
__P ((void));
288 /* Call WARNFUN with a warning message when memory usage is high. */
289 extern void memory_warnings
__P ((__ptr_t __start
,
290 void (*__warnfun
) __P ((__const
char *))));
293 /* Relocating allocator. */
295 /* Allocate SIZE bytes, and store the address in *HANDLEPTR. */
296 extern __ptr_t r_alloc
__P ((__ptr_t
*__handleptr
, size_t __size
));
298 /* Free the storage allocated in HANDLEPTR. */
299 extern void r_alloc_free
__P ((__ptr_t
*__handleptr
));
301 /* Adjust the block at HANDLEPTR to be SIZE bytes long. */
302 extern __ptr_t r_re_alloc
__P ((__ptr_t
*__handleptr
, size_t __size
));
309 #endif /* malloc.h */
310 /* Memory allocator `malloc'.
311 Copyright 1990, 1991, 1992, 1993 Free Software Foundation
312 Written May 1989 by Mike Haertel.
314 This library is free software; you can redistribute it and/or
315 modify it under the terms of the GNU Library General Public License as
316 published by the Free Software Foundation; either version 2 of the
317 License, or (at your option) any later version.
319 This library is distributed in the hope that it will be useful,
320 but WITHOUT ANY WARRANTY; without even the implied warranty of
321 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
322 Library General Public License for more details.
324 You should have received a copy of the GNU Library General Public
325 License along with this library; see the file COPYING.LIB. If
326 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
327 Cambridge, MA 02139, USA.
329 The author may be reached (Email) at the address mike@ai.mit.edu,
330 or (US mail) as Mike Haertel c/o Free Software Foundation. */
332 #ifndef _MALLOC_INTERNAL
333 #define _MALLOC_INTERNAL
338 /* How to really get more memory. */
339 __ptr_t (*__morecore
) __P ((ptrdiff_t __size
)) = __vms_morecore
;
341 /* How to really get more memory. */
342 __ptr_t (*__morecore
) __P ((ptrdiff_t __size
)) = __default_morecore
;
345 /* Debugging hook for `malloc'. */
347 __ptr_t (*__malloc_hook
) __P ((size_t __size
)) = __vms_malloc
;
349 __ptr_t (*__malloc_hook
) __P ((size_t __size
));
352 /* Pointer to the base of the first block. */
355 /* Block information table. Allocated with align/__free (not malloc/free). */
356 malloc_info
*_heapinfo
;
358 /* Number of info entries. */
359 static size_t heapsize
;
361 /* Search index in the info table. */
364 /* Limit of valid info table indices. */
367 /* Free lists for each fragment size. */
368 struct list _fraghead
[BLOCKLOG
];
370 /* Instrumentation. */
376 /* Are you experienced? */
377 int __malloc_initialized
;
379 void (*__after_morecore_hook
) __P ((void));
381 /* Aligned allocation. */
382 static __ptr_t align
__P ((size_t));
388 unsigned long int adj
;
390 result
= (*__morecore
) (size
);
391 adj
= (unsigned long int) ((unsigned long int) ((char *) result
-
392 (char *) NULL
)) % BLOCKSIZE
;
395 adj
= BLOCKSIZE
- adj
;
396 (void) (*__morecore
) (adj
);
397 result
= (char *) result
+ adj
;
400 if (__after_morecore_hook
)
401 (*__after_morecore_hook
) ();
406 /* Set everything up and remember that we have. */
407 static int initialize
__P ((void));
412 extern VMS_present_buffer();
413 printf("__malloc_initialized = %d\n", __malloc_initialized
);
414 VMS_present_buffer();
416 heapsize
= HEAP
/ BLOCKSIZE
;
417 _heapinfo
= (malloc_info
*) align (heapsize
* sizeof (malloc_info
));
418 if (_heapinfo
== NULL
)
420 memset (_heapinfo
, 0, heapsize
* sizeof (malloc_info
));
421 _heapinfo
[0].free
.size
= 0;
422 _heapinfo
[0].free
.next
= _heapinfo
[0].free
.prev
= 0;
424 _heapbase
= (char *) _heapinfo
;
427 printf("_heapbase = 0%o/0x%x/%d\n", _heapbase
, _heapbase
, _heapbase
);
430 __malloc_initialized
= 1;
434 /* Get neatly aligned memory, initializing or
435 growing the heap info table as necessary. */
436 static __ptr_t morecore
__P ((size_t));
442 malloc_info
*newinfo
, *oldinfo
;
445 result
= align (size
);
449 /* Check if we need to grow the info table. */
450 if ((size_t) BLOCK ((char *) result
+ size
) > heapsize
)
453 while ((size_t) BLOCK ((char *) result
+ size
) > newsize
)
455 newinfo
= (malloc_info
*) align (newsize
* sizeof (malloc_info
));
458 (*__lesscore
) (result
, size
);
461 memset (newinfo
, 0, newsize
* sizeof (malloc_info
));
462 memcpy (newinfo
, _heapinfo
, heapsize
* sizeof (malloc_info
));
464 newinfo
[BLOCK (oldinfo
)].busy
.type
= 0;
465 newinfo
[BLOCK (oldinfo
)].busy
.info
.size
466 = BLOCKIFY (heapsize
* sizeof (malloc_info
));
468 _free_internal (oldinfo
);
472 _heaplimit
= BLOCK ((char *) result
+ size
);
476 /* Allocate memory from the heap. */
482 size_t block
, blocks
, lastblocks
, start
;
489 if (__malloc_hook
!= NULL
)
490 return (*__malloc_hook
) (size
);
492 if (!__malloc_initialized
)
496 if (size
< sizeof (struct list
))
497 size
= sizeof (struct list
);
499 /* Determine the allocation policy based on the request size. */
500 if (size
<= BLOCKSIZE
/ 2)
502 /* Small allocation to receive a fragment of a block.
503 Determine the logarithm to base two of the fragment size. */
504 register size_t log
= 1;
506 while ((size
/= 2) != 0)
509 /* Look in the fragment lists for a
510 free fragment of the desired size. */
511 next
= _fraghead
[log
].next
;
514 /* There are free fragments of this size.
515 Pop a fragment out of the fragment list and return it.
516 Update the block's nfree and first counters. */
517 result
= (__ptr_t
) next
;
518 next
->prev
->next
= next
->next
;
519 if (next
->next
!= NULL
)
520 next
->next
->prev
= next
->prev
;
521 block
= BLOCK (result
);
522 if (--_heapinfo
[block
].busy
.info
.frag
.nfree
!= 0)
523 _heapinfo
[block
].busy
.info
.frag
.first
= (unsigned long int)
524 ((unsigned long int) ((char *) next
->next
- (char *) NULL
)
527 /* Update the statistics. */
529 _bytes_used
+= 1 << log
;
531 _bytes_free
-= 1 << log
;
535 /* No free fragments of the desired size, so get a new block
536 and break it into fragments, returning the first. */
537 result
= malloc (BLOCKSIZE
);
541 /* Link all fragments but the first into the free list. */
542 for (i
= 1; i
< (size_t) (BLOCKSIZE
>> log
); ++i
)
544 next
= (struct list
*) ((char *) result
+ (i
<< log
));
546 printf("DEBUG: malloc (%d): next = %p\n", size
, next
);
548 next
->next
= _fraghead
[log
].next
;
549 next
->prev
= &_fraghead
[log
];
550 next
->prev
->next
= next
;
551 if (next
->next
!= NULL
)
552 next
->next
->prev
= next
;
555 /* Initialize the nfree and first counters for this block. */
556 block
= BLOCK (result
);
557 _heapinfo
[block
].busy
.type
= log
;
558 _heapinfo
[block
].busy
.info
.frag
.nfree
= i
- 1;
559 _heapinfo
[block
].busy
.info
.frag
.first
= i
- 1;
561 _chunks_free
+= (BLOCKSIZE
>> log
) - 1;
562 _bytes_free
+= BLOCKSIZE
- (1 << log
);
563 _bytes_used
-= BLOCKSIZE
- (1 << log
);
568 /* Large allocation to receive one or more blocks.
569 Search the free list in a circle starting at the last place visited.
570 If we loop completely around without finding a large enough
571 space we will have to get more memory from the system. */
572 blocks
= BLOCKIFY (size
);
573 start
= block
= _heapindex
;
574 while (_heapinfo
[block
].free
.size
< blocks
)
576 block
= _heapinfo
[block
].free
.next
;
579 /* Need to get more from the system. Check to see if
580 the new core will be contiguous with the final free
581 block; if so we don't need to get as much. */
582 block
= _heapinfo
[0].free
.prev
;
583 lastblocks
= _heapinfo
[block
].free
.size
;
584 if (_heaplimit
!= 0 && block
+ lastblocks
== _heaplimit
&&
585 (*__morecore
) (0) == ADDRESS (block
+ lastblocks
) &&
586 (morecore ((blocks
- lastblocks
) * BLOCKSIZE
)) != NULL
)
588 _heapinfo
[block
].free
.size
= blocks
;
589 _bytes_free
+= (blocks
- lastblocks
) * BLOCKSIZE
;
592 result
= morecore (blocks
* BLOCKSIZE
);
595 block
= BLOCK (result
);
596 _heapinfo
[block
].busy
.type
= 0;
597 _heapinfo
[block
].busy
.info
.size
= blocks
;
599 _bytes_used
+= blocks
* BLOCKSIZE
;
604 /* At this point we have found a suitable free list entry.
605 Figure out how to remove what we need from the list. */
606 result
= ADDRESS (block
);
607 if (_heapinfo
[block
].free
.size
> blocks
)
609 /* The block we found has a bit left over,
610 so relink the tail end back into the free list. */
611 _heapinfo
[block
+ blocks
].free
.size
612 = _heapinfo
[block
].free
.size
- blocks
;
613 _heapinfo
[block
+ blocks
].free
.next
614 = _heapinfo
[block
].free
.next
;
615 _heapinfo
[block
+ blocks
].free
.prev
616 = _heapinfo
[block
].free
.prev
;
617 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
618 = _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
619 = _heapindex
= block
+ blocks
;
623 /* The block exactly matches our requirements,
624 so just remove it from the list. */
625 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
626 = _heapinfo
[block
].free
.prev
;
627 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
628 = _heapindex
= _heapinfo
[block
].free
.next
;
632 _heapinfo
[block
].busy
.type
= 0;
633 _heapinfo
[block
].busy
.info
.size
= blocks
;
635 _bytes_used
+= blocks
* BLOCKSIZE
;
636 _bytes_free
-= blocks
* BLOCKSIZE
;
641 /* Free a block of memory allocated by `malloc'.
642 Copyright 1990, 1991, 1992 Free Software Foundation
643 Written May 1989 by Mike Haertel.
645 This library is free software; you can redistribute it and/or
646 modify it under the terms of the GNU Library General Public License as
647 published by the Free Software Foundation; either version 2 of the
648 License, or (at your option) any later version.
650 This library is distributed in the hope that it will be useful,
651 but WITHOUT ANY WARRANTY; without even the implied warranty of
652 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
653 Library General Public License for more details.
655 You should have received a copy of the GNU Library General Public
656 License along with this library; see the file COPYING.LIB. If
657 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
658 Cambridge, MA 02139, USA.
660 The author may be reached (Email) at the address mike@ai.mit.edu,
661 or (US mail) as Mike Haertel c/o Free Software Foundation. */
663 #ifndef _MALLOC_INTERNAL
664 #define _MALLOC_INTERNAL
669 /* How to really get more memory. */
670 __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
,ptrdiff_t __size
)) = __vms_lesscore
;
672 /* How to really get more memory. */
673 __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
,ptrdiff_t __size
)) = __default_lesscore
;
676 /* Debugging hook for free. */
678 void (*__free_hook
) __P ((__ptr_t __ptr
)) = __vms_free
;
680 void (*__free_hook
) __P ((__ptr_t __ptr
));
683 /* List of blocks allocated by memalign. */
684 struct alignlist
*_aligned_blocks
= NULL
;
686 /* Return memory to the heap.
687 Like `free' but don't call a __free_hook if there is one. */
693 size_t block
, blocks
;
695 struct list
*prev
, *next
;
699 type
= _heapinfo
[block
].busy
.type
;
703 /* Get as many statistics as early as we can. */
705 _bytes_used
-= _heapinfo
[block
].busy
.info
.size
* BLOCKSIZE
;
706 _bytes_free
+= _heapinfo
[block
].busy
.info
.size
* BLOCKSIZE
;
708 /* Find the free cluster previous to this one in the free list.
709 Start searching at the last block referenced; this may benefit
710 programs with locality of allocation. */
714 i
= _heapinfo
[i
].free
.prev
;
718 i
= _heapinfo
[i
].free
.next
;
719 while (i
> 0 && i
< block
);
720 i
= _heapinfo
[i
].free
.prev
;
723 /* Determine how to link this block into the free list. */
724 if (block
== i
+ _heapinfo
[i
].free
.size
)
726 /* Coalesce this block with its predecessor. */
727 _heapinfo
[i
].free
.size
+= _heapinfo
[block
].busy
.info
.size
;
732 /* Really link this block back into the free list. */
733 _heapinfo
[block
].free
.size
= _heapinfo
[block
].busy
.info
.size
;
734 _heapinfo
[block
].free
.next
= _heapinfo
[i
].free
.next
;
735 _heapinfo
[block
].free
.prev
= i
;
736 _heapinfo
[i
].free
.next
= block
;
737 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
= block
;
741 /* Now that the block is linked in, see if we can coalesce it
742 with its successor (by deleting its successor from the list
743 and adding in its size). */
744 if (block
+ _heapinfo
[block
].free
.size
== _heapinfo
[block
].free
.next
)
746 _heapinfo
[block
].free
.size
747 += _heapinfo
[_heapinfo
[block
].free
.next
].free
.size
;
748 _heapinfo
[block
].free
.next
749 = _heapinfo
[_heapinfo
[block
].free
.next
].free
.next
;
750 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
= block
;
754 /* Now see if we can return stuff to the system. */
755 blocks
= _heapinfo
[block
].free
.size
;
756 if (blocks
>= FINAL_FREE_BLOCKS
&& block
+ blocks
== _heaplimit
757 && (*__morecore
) (0) == ADDRESS (block
+ blocks
))
759 register size_t bytes
= blocks
* BLOCKSIZE
;
760 _heaplimit
-= blocks
;
761 (*__lesscore
) (ADDRESS(block
), bytes
);
762 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
763 = _heapinfo
[block
].free
.next
;
764 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
765 = _heapinfo
[block
].free
.prev
;
766 block
= _heapinfo
[block
].free
.prev
;
768 _bytes_free
-= bytes
;
771 /* Set the next search to begin at this block. */
776 /* Do some of the statistics. */
778 _bytes_used
-= 1 << type
;
780 _bytes_free
+= 1 << type
;
782 /* Get the address of the first free fragment in this block. */
783 prev
= (struct list
*) ((char *) ADDRESS (block
) +
784 (_heapinfo
[block
].busy
.info
.frag
.first
<< type
));
786 printf("_free_internal(0%o/0x%x/%d) :\n", ptr
, ptr
, ptr
);
787 printf(" block = %d, type = %d, prev = 0%o/0x%x/%d\n",
788 block
, type
, prev
, prev
, prev
);
789 printf(" _heapinfo[block=%d].busy.info.frag.nfree = %d\n",
791 _heapinfo
[block
].busy
.info
.frag
.nfree
);
794 if (_heapinfo
[block
].busy
.info
.frag
.nfree
== (BLOCKSIZE
>> type
) - 1)
796 /* If all fragments of this block are free, remove them
797 from the fragment list and free the whole block. */
799 for (i
= 1; i
< (size_t) (BLOCKSIZE
>> type
); ++i
)
801 prev
->prev
->next
= next
;
803 next
->prev
= prev
->prev
;
804 _heapinfo
[block
].busy
.type
= 0;
805 _heapinfo
[block
].busy
.info
.size
= 1;
807 /* Keep the statistics accurate. */
809 _bytes_used
+= BLOCKSIZE
;
810 _chunks_free
-= BLOCKSIZE
>> type
;
811 _bytes_free
-= BLOCKSIZE
;
813 free (ADDRESS (block
));
815 else if (_heapinfo
[block
].busy
.info
.frag
.nfree
!= 0)
817 /* If some fragments of this block are free, link this
818 fragment into the fragment list after the first free
819 fragment of this block. */
821 printf("There's a bug hiding here (%s:%d), so I will print some values\n", __FILE__
, __LINE__
);
823 next
= (struct list
*) ptr
;
825 printf(" (struct list *)next (0%o / 0x%x / %d) ->\n", next
, next
, next
);
826 printf(" next = 0%o / 0x%x / %d\n", next
->next
,next
->next
,next
->next
);
827 printf(" prev = 0%o / 0x%x / %d\n", next
->prev
,next
->prev
,next
->prev
);
828 printf(" (struct list *)prev (0%o / 0x%x / %d)->\n", prev
, prev
, prev
);
829 printf(" next = 0%o / 0x%x / %d\n", prev
->next
,prev
->next
,prev
->next
);
830 printf(" prev = 0%o / 0x%x / %d\n", prev
->prev
,prev
->prev
,prev
->prev
);
832 next
->next
= prev
->next
;
835 if (next
->next
!= NULL
)
836 next
->next
->prev
= next
;
837 ++_heapinfo
[block
].busy
.info
.frag
.nfree
;
841 /* No fragments of this block are free, so link this
842 fragment into the fragment list and announce that
843 it is the first free fragment of this block. */
844 prev
= (struct list
*) ptr
;
845 _heapinfo
[block
].busy
.info
.frag
.nfree
= 1;
846 _heapinfo
[block
].busy
.info
.frag
.first
= (unsigned long int)
847 ((unsigned long int) ((char *) ptr
- (char *) NULL
)
848 % BLOCKSIZE
>> type
);
849 prev
->next
= _fraghead
[type
].next
;
850 prev
->prev
= &_fraghead
[type
];
851 prev
->prev
->next
= prev
;
852 if (prev
->next
!= NULL
)
853 prev
->next
->prev
= prev
;
859 /* Return memory to the heap. */
864 register struct alignlist
*l
;
869 for (l
= _aligned_blocks
; l
!= NULL
; l
= l
->next
)
870 if (l
->aligned
== ptr
)
872 l
->aligned
= NULL
; /* Mark the slot in the list as free. */
877 if (__free_hook
!= NULL
)
878 (*__free_hook
) (ptr
);
880 _free_internal (ptr
);
882 /* Change the size of a block allocated by `malloc'.
883 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
884 Written May 1989 by Mike Haertel.
886 This library is free software; you can redistribute it and/or
887 modify it under the terms of the GNU Library General Public License as
888 published by the Free Software Foundation; either version 2 of the
889 License, or (at your option) any later version.
891 This library is distributed in the hope that it will be useful,
892 but WITHOUT ANY WARRANTY; without even the implied warranty of
893 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
894 Library General Public License for more details.
896 You should have received a copy of the GNU Library General Public
897 License along with this library; see the file COPYING.LIB. If
898 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
899 Cambridge, MA 02139, USA.
901 The author may be reached (Email) at the address mike@ai.mit.edu,
902 or (US mail) as Mike Haertel c/o Free Software Foundation. */
904 #ifndef _MALLOC_INTERNAL
905 #define _MALLOC_INTERNAL
909 #define min(A, B) ((A) < (B) ? (A) : (B))
911 /* Debugging hook for realloc. */
913 __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
)) = __vms_realloc
;
915 __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
));
918 /* Resize the given region to the new size, returning a pointer
919 to the (possibly moved) region. This is optimized for speed;
920 some benchmarks seem to indicate that greater compactness is
921 achieved by unconditionally allocating and copying to a
922 new region. This module has incestuous knowledge of the
923 internals of both free and malloc. */
931 size_t block
, blocks
, oldlimit
;
938 else if (ptr
== NULL
)
939 return malloc (size
);
941 if (__realloc_hook
!= NULL
)
942 return (*__realloc_hook
) (ptr
, size
);
946 type
= _heapinfo
[block
].busy
.type
;
950 /* Maybe reallocate a large block to a small fragment. */
951 if (size
<= BLOCKSIZE
/ 2)
953 result
= malloc (size
);
956 memcpy (result
, ptr
, size
);
962 /* The new size is a large allocation as well;
963 see if we can hold it in place. */
964 blocks
= BLOCKIFY (size
);
965 if (blocks
< _heapinfo
[block
].busy
.info
.size
)
967 /* The new size is smaller; return
968 excess memory to the free list. */
969 _heapinfo
[block
+ blocks
].busy
.type
= 0;
970 _heapinfo
[block
+ blocks
].busy
.info
.size
971 = _heapinfo
[block
].busy
.info
.size
- blocks
;
972 _heapinfo
[block
].busy
.info
.size
= blocks
;
973 free (ADDRESS (block
+ blocks
));
976 else if (blocks
== _heapinfo
[block
].busy
.info
.size
)
977 /* No size change necessary. */
981 /* Won't fit, so allocate a new region that will.
982 Free the old region first in case there is sufficient
983 adjacent free space to grow without moving. */
984 blocks
= _heapinfo
[block
].busy
.info
.size
;
985 /* Prevent free from actually returning memory to the system. */
986 oldlimit
= _heaplimit
;
989 _heaplimit
= oldlimit
;
990 result
= malloc (size
);
993 /* Now we're really in trouble. We have to unfree
994 the thing we just freed. Unfortunately it might
995 have been coalesced with its neighbors. */
996 if (_heapindex
== block
)
997 (void) malloc (blocks
* BLOCKSIZE
);
1000 __ptr_t previous
= malloc ((block
- _heapindex
) * BLOCKSIZE
);
1001 (void) malloc (blocks
* BLOCKSIZE
);
1007 memmove (result
, ptr
, blocks
* BLOCKSIZE
);
1012 /* Old size is a fragment; type is logarithm
1013 to base two of the fragment size. */
1014 if (size
> (size_t) (1 << (type
- 1)) && size
<= (size_t) (1 << type
))
1015 /* The new size is the same kind of fragment. */
1019 /* The new size is different; allocate a new space,
1020 and copy the lesser of the new size and the old. */
1021 result
= malloc (size
);
1024 memcpy (result
, ptr
, min (size
, (size_t) 1 << type
));
1032 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1034 This library is free software; you can redistribute it and/or
1035 modify it under the terms of the GNU Library General Public License as
1036 published by the Free Software Foundation; either version 2 of the
1037 License, or (at your option) any later version.
1039 This library is distributed in the hope that it will be useful,
1040 but WITHOUT ANY WARRANTY; without even the implied warranty of
1041 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1042 Library General Public License for more details.
1044 You should have received a copy of the GNU Library General Public
1045 License along with this library; see the file COPYING.LIB. If
1046 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1047 Cambridge, MA 02139, USA.
1049 The author may be reached (Email) at the address mike@ai.mit.edu,
1050 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1052 #ifndef _MALLOC_INTERNAL
1053 #define _MALLOC_INTERNAL
1057 /* Allocate an array of NMEMB elements each SIZE bytes long.
1058 The entire array is initialized to zeros. */
1060 calloc (nmemb
, size
)
1061 register size_t nmemb
;
1062 register size_t size
;
1064 register __ptr_t result
= malloc (nmemb
* size
);
1067 (void) memset (result
, 0, nmemb
* size
);
1071 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1072 This file is part of the GNU C Library.
1074 The GNU C Library 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 2, or (at your option)
1079 The GNU C Library 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.
1084 You should have received a copy of the GNU General Public License
1085 along with the GNU C Library; see the file COPYING. If not, write to
1086 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
1088 #ifndef _MALLOC_INTERNAL
1089 #define _MALLOC_INTERNAL
1093 #ifndef __GNU_LIBRARY__
1100 extern __ptr_t __sbrk
__P ((int increment
));
1106 #if defined(emacs) && defined(VMS)
1107 /* Dumping of Emacs on VMS does not include the heap!
1108 So let's make a huge array from which initial data will be
1111 VMS_ALLOCATION_SIZE is the amount of memory we preallocate.
1112 We don't want it to be too large, because it only gives a larger
1113 dump file. The way to check how much is really used is to
1114 make VMS_ALLOCATION_SIZE very large, to link Emacs with the
1115 debugger, run Emacs, check how much was allocated. Then set
1116 VMS_ALLOCATION_SIZE to something suitable, recompile gmalloc,
1117 relink Emacs, and you should be off.
1119 N.B. This is experimental, but it worked quite fine on Emacs 18.
1121 #ifndef VMS_ALLOCATION_SIZE
1122 #define VMS_ALLOCATION_SIZE (512*(512+128))
1125 int vms_out_initial
= 0;
1126 char vms_initial_buffer
[VMS_ALLOCATION_SIZE
];
1127 char *vms_current_brk
= vms_initial_buffer
;
1128 char *vms_end_brk
= &vms_initial_buffer
[VMS_ALLOCATION_SIZE
-1];
1131 __vms_initial_morecore (increment
)
1132 ptrdiff_t increment
;
1134 __ptr_t result
= NULL
;
1137 /* It's far easier to make the alignment here than to make a
1138 kludge in align () */
1140 printf(">>>foo... %p...", vms_current_brk
);
1142 vms_current_brk
+= (BLOCKSIZE
- ((unsigned long) vms_current_brk
1143 & (BLOCKSIZE
- 1))) & (BLOCKSIZE
- 1);
1145 printf("bar... %p. (%d)\n", vms_current_brk
, increment
);
1147 temp
= vms_current_brk
+ (int) increment
;
1148 if (temp
<= vms_end_brk
)
1151 result
= vms_current_brk
;
1154 vms_current_brk
= temp
;
1160 __vms_initial_lesscore (ptr
, size
)
1164 if (ptr
>= vms_initial_buffer
1165 && ptr
< vms_initial_buffer
+VMS_ALLOCATION_SIZE
)
1167 vms_current_brk
= ptr
;
1168 return vms_current_brk
;
1170 return vms_current_brk
;
1173 VMS_present_buffer()
1175 printf("Vms initial buffer starts at 0%o/0x%x/%d and ends at 0%o/0x%x/%d\n",
1176 vms_initial_buffer
, vms_initial_buffer
, vms_initial_buffer
,
1177 vms_end_brk
, vms_end_brk
, vms_end_brk
);
1179 #endif /* defined(emacs) && defined(VMS) */
1182 /* Unfortunatelly, the VAX C sbrk() is buggy. For example, it returns
1183 memory in 512 byte chunks (not a bug, but there's more), AND it
1184 adds an extra 512 byte chunk if you ask for a multiple of 512
1185 bytes (you ask for 512 bytes, you get 1024 bytes...). And also,
1186 the VAX C sbrk does not handle negative increments...
1187 There's a similar problem with brk(). Even if you set the break
1188 to an even page boundary, it gives you one extra page... */
1190 static char vms_brk_info_fetched
= -1; /* -1 if this is the first time, otherwise
1191 bit 0 set if 'increment' needs adjustment
1192 bit 1 set if the value to brk() needs adjustment */
1193 static char *vms_brk_start
= 0;
1194 static char *vms_brk_end
= 0;
1195 static char *vms_brk_current
= 0;
1198 /* Allocate INCREMENT more bytes of data space,
1199 and return the start of data space, or NULL on errors.
1200 If INCREMENT is negative, shrink data space. */
1202 __default_morecore (increment
)
1203 ptrdiff_t increment
;
1210 printf("DEBUG: morecore: increment = %x\n", increment
);
1211 printf(" @ start: vms_brk_info_fetched = %x\n", vms_brk_info_fetched
);
1212 printf(" vms_brk_start = %p\n", vms_brk_start
);
1213 printf(" vms_brk_current = %p\n", vms_brk_current
);
1214 printf(" vms_brk_end = %p\n", vms_brk_end
);
1218 if (vms_brk_info_fetched
< 0)
1220 vms_brk_current
= vms_brk_start
= __sbrk (512);
1221 vms_brk_end
= __sbrk (0);
1222 if (vms_brk_end
- vms_brk_current
== 1024)
1223 vms_brk_info_fetched
= 1;
1225 vms_brk_info_fetched
= 0;
1226 vms_brk_end
= brk(vms_brk_start
);
1227 if (vms_brk_end
!= vms_brk_start
)
1228 vms_brk_info_fetched
|= 2;
1230 printf("vms_brk_info_fetched = %x\n", vms_brk_info_fetched
);
1231 printf(" vms_brk_start = %p\n", vms_brk_start
);
1232 printf(" vms_brk_current = %p\n", vms_brk_current
);
1233 printf(" vms_brk_end = %p\n", vms_brk_end
);
1240 printf("BZZZZZT! ERROR: __default_morecore does NOT take negative args\n");
1246 result
= vms_brk_current
;
1247 temp
= vms_brk_current
+ increment
;
1249 if (temp
> vms_brk_end
)
1254 if (foo
== vms_brk_end
)
1256 increment
= temp
- vms_brk_end
;
1257 if (increment
> (vms_brk_info_fetched
& 1))
1258 increment
-= (vms_brk_info_fetched
& 1);
1259 foo
= __sbrk(increment
);
1261 printf("__sbrk(%d) --> %p\n", increment
, foo
);
1263 if (foo
== (__ptr_t
) -1)
1271 result
= __sbrk (increment
);
1273 if (result
== (__ptr_t
) -1)
1276 temp
= result
+ increment
;
1279 vms_brk_end
= __sbrk(0);
1281 vms_brk_current
= temp
;
1283 printf("vms_brk_current = %p\n", vms_brk_current
);
1284 printf(" vms_brk_end = %p\n", vms_brk_end
);
1289 printf(" nothing more...\n");
1292 /* OK, so the user wanted to check where the heap limit is. Let's
1293 see if the system thinks it is where we think it is. */
1295 if (temp
!= vms_brk_end
)
1297 /* the value has changed.
1298 Let's trust the system and modify our value */
1299 vms_brk_current
= vms_brk_end
= temp
;
1301 return vms_brk_current
;
1304 result
= __sbrk ((int) increment
);
1305 if (result
== (__ptr_t
) -1)
1312 __default_lesscore (ptr
, size
)
1317 if (vms_brk_end
!= 0)
1319 vms_brk_current
= ptr
;
1320 if (vms_brk_current
< vms_brk_start
)
1321 vms_brk_current
= vms_brk_start
;
1322 vms_brk_end
= (char *) vms_brk_current
-
1323 ((vms_brk_info_fetched
>> 1) & 1);
1325 printf("<<<bar... %p (%p (%p, %d))...",
1326 vms_brk_end
, vms_brk_current
, ptr
, size
);
1328 vms_brk_end
= __brk (vms_brk_end
);
1330 printf("foo... %p.\n", vms_brk_end
);
1334 return vms_brk_current
;
1336 __default_morecore (-size
);
1340 /* Allocate memory on a page boundary.
1341 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1343 This library is free software; you can redistribute it and/or
1344 modify it under the terms of the GNU Library General Public License as
1345 published by the Free Software Foundation; either version 2 of the
1346 License, or (at your option) any later version.
1348 This library is distributed in the hope that it will be useful,
1349 but WITHOUT ANY WARRANTY; without even the implied warranty of
1350 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1351 Library General Public License for more details.
1353 You should have received a copy of the GNU Library General Public
1354 License along with this library; see the file COPYING.LIB. If
1355 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1356 Cambridge, MA 02139, USA.
1358 The author may be reached (Email) at the address mike@ai.mit.edu,
1359 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1361 #ifndef _MALLOC_INTERNAL
1362 #define _MALLOC_INTERNAL
1366 #if defined (emacs) || defined (HAVE_CONFIG_H)
1370 #ifdef __GNU_LIBRARY__
1371 extern size_t __getpagesize
__P ((void));
1373 #if !defined(USG) && !defined(VMS)
1374 extern size_t getpagesize
__P ((void));
1375 #define __getpagesize() getpagesize()
1377 #include <sys/param.h>
1378 #ifdef EXEC_PAGESIZE
1379 #define __getpagesize() EXEC_PAGESIZE
1380 #else /* No EXEC_PAGESIZE. */
1384 #endif /* No CLSIZE. */
1385 #define __getpagesize() (NBPG * CLSIZE)
1386 #else /* No NBPG. */
1387 #define __getpagesize() NBPC
1389 #endif /* EXEC_PAGESIZE. */
1393 static size_t pagesize
;
1400 pagesize
= __getpagesize ();
1402 return memalign (pagesize
, size
);
1404 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1406 This library is free software; you can redistribute it and/or
1407 modify it under the terms of the GNU Library General Public License as
1408 published by the Free Software Foundation; either version 2 of the
1409 License, or (at your option) any later version.
1411 This library is distributed in the hope that it will be useful,
1412 but WITHOUT ANY WARRANTY; without even the implied warranty of
1413 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1414 Library General Public License for more details.
1416 You should have received a copy of the GNU Library General Public
1417 License along with this library; see the file COPYING.LIB. If
1418 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1419 Cambridge, MA 02139, USA. */
1421 #ifndef _MALLOC_INTERNAL
1422 #define _MALLOC_INTERNAL
1427 memalign (alignment
, size
)
1432 unsigned long int adj
;
1434 size
= ((size
+ alignment
- 1) / alignment
) * alignment
;
1436 result
= malloc (size
);
1439 adj
= (unsigned long int) ((unsigned long int) ((char *) result
-
1440 (char *) NULL
)) % alignment
;
1443 struct alignlist
*l
;
1444 for (l
= _aligned_blocks
; l
!= NULL
; l
= l
->next
)
1445 if (l
->aligned
== NULL
)
1446 /* This slot is free. Use it. */
1450 l
= (struct alignlist
*) malloc (sizeof (struct alignlist
));
1458 result
= l
->aligned
= (char *) result
+ alignment
- adj
;
1459 l
->next
= _aligned_blocks
;
1460 _aligned_blocks
= l
;
1467 struct vms_malloc_data
1469 int __malloc_initialized
;
1471 malloc_info
*_heapinfo
;
1475 size_t _chunks_used
;
1477 size_t _chunks_free
;
1479 } ____vms_malloc_data
[] =
1481 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1482 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1485 struct vms_core_routines
1487 __ptr_t (*__morecore
) __P ((ptrdiff_t increment
));
1488 __ptr_t (*__lesscore
) __P ((__ptr_t address
, ptrdiff_t increment
));
1489 } ____vms_core_routines
[] =
1491 { __vms_initial_morecore
, __vms_initial_lesscore
},
1492 { __default_morecore
, __default_lesscore
},
1496 static int current_vms_data
= -1;
1497 static int current_vms_core_routines
= 0;
1499 static void use_vms_core_routines (int i
)
1501 current_vms_core_routines
= i
;
1502 current_vms_data
= i
;
1505 static void use_vms_data (int i
)
1507 use_vms_core_routines (i
);
1508 __malloc_initialized
= ____vms_malloc_data
[i
].__malloc_initialized
;
1509 _heapbase
= ____vms_malloc_data
[i
]._heapbase
;
1510 _heapinfo
= ____vms_malloc_data
[i
]._heapinfo
;
1511 heapsize
= ____vms_malloc_data
[i
].heapsize
;
1512 _heapindex
= ____vms_malloc_data
[i
]._heapindex
;
1513 _heaplimit
= ____vms_malloc_data
[i
]._heaplimit
;
1514 _chunks_used
= ____vms_malloc_data
[i
]._chunks_used
;
1515 _bytes_used
= ____vms_malloc_data
[i
]._bytes_used
;
1516 _chunks_free
= ____vms_malloc_data
[i
]._chunks_free
;
1517 _bytes_free
= ____vms_malloc_data
[i
]._bytes_free
;
1520 static void store_vms_data (int i
)
1522 ____vms_malloc_data
[i
].__malloc_initialized
= __malloc_initialized
;
1523 ____vms_malloc_data
[i
]._heapbase
= _heapbase
;
1524 ____vms_malloc_data
[i
]._heapinfo
= _heapinfo
;
1525 ____vms_malloc_data
[i
].heapsize
= heapsize
;
1526 ____vms_malloc_data
[i
]._heapindex
= _heapindex
;
1527 ____vms_malloc_data
[i
]._heaplimit
= _heaplimit
;
1528 ____vms_malloc_data
[i
]._chunks_used
= _chunks_used
;
1529 ____vms_malloc_data
[i
]._bytes_used
= _bytes_used
;
1530 ____vms_malloc_data
[i
]._chunks_free
= _chunks_free
;
1531 ____vms_malloc_data
[i
]._bytes_free
= _bytes_free
;
1534 static void store_current_vms_data ()
1536 switch (current_vms_data
)
1540 store_vms_data (current_vms_data
);
1545 __ptr_t
__vms_morecore (increment
)
1546 ptrdiff_t increment
;
1549 (*____vms_core_routines
[current_vms_core_routines
].__morecore
) (increment
);
1552 __ptr_t
__vms_lesscore (ptr
, increment
)
1554 ptrdiff_t increment
;
1557 (*____vms_core_routines
[current_vms_core_routines
].__lesscore
) (ptr
,increment
);
1560 __ptr_t
__vms_malloc (size
)
1564 int old_current_vms_data
= current_vms_data
;
1568 store_current_vms_data ();
1570 if (____vms_malloc_data
[0]._heapbase
!= 0)
1573 use_vms_core_routines (0);
1574 result
= malloc (size
);
1579 result
= malloc (size
);
1581 vms_out_initial
= 1;
1583 __malloc_hook
= __vms_malloc
;
1584 if (old_current_vms_data
!= -1)
1585 use_vms_data (current_vms_data
);
1589 void __vms_free (ptr
)
1592 int old_current_vms_data
= current_vms_data
;
1596 store_current_vms_data ();
1598 if (ptr
>= vms_initial_buffer
&& ptr
<= vms_end_brk
)
1609 if (_chunks_free
== 0 && _chunks_used
== 0)
1610 vms_out_initial
= 0;
1612 __free_hook
= __vms_free
;
1613 if (old_current_vms_data
!= -1)
1614 use_vms_data (current_vms_data
);
1617 __ptr_t
__vms_realloc (ptr
, size
)
1622 int old_current_vms_data
= current_vms_data
;
1626 store_current_vms_data ();
1628 if (ptr
>= vms_initial_buffer
&& ptr
<= vms_end_brk
)
1631 result
= realloc (ptr
, size
);
1637 result
= realloc (ptr
, size
);
1640 __realloc_hook
= __vms_realloc
;
1641 if (old_current_vms_data
!= -1)
1642 use_vms_data (current_vms_data
);
1646 /* Standard debugging hooks for `malloc'.
1647 Copyright 1990, 1991, 1992 Free Software Foundation
1648 Written May 1989 by Mike Haertel.
1650 This library is free software; you can redistribute it and/or
1651 modify it under the terms of the GNU Library General Public License as
1652 published by the Free Software Foundation; either version 2 of the
1653 License, or (at your option) any later version.
1655 This library is distributed in the hope that it will be useful,
1656 but WITHOUT ANY WARRANTY; without even the implied warranty of
1657 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1658 Library General Public License for more details.
1660 You should have received a copy of the GNU Library General Public
1661 License along with this library; see the file COPYING.LIB. If
1662 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1663 Cambridge, MA 02139, USA.
1665 The author may be reached (Email) at the address mike@ai.mit.edu,
1666 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1668 #ifndef _MALLOC_INTERNAL
1669 #define _MALLOC_INTERNAL
1673 /* Old hook values. */
1674 static void (*old_free_hook
) __P ((__ptr_t ptr
));
1675 static __ptr_t (*old_malloc_hook
) __P ((size_t size
));
1676 static __ptr_t (*old_realloc_hook
) __P ((__ptr_t ptr
, size_t size
));
1678 /* Function to call when something awful happens. */
1679 static void (*abortfunc
) __P ((void));
1681 /* Arbitrary magical numbers. */
1682 #define MAGICWORD 0xfedabeeb
1683 #define MAGICBYTE ((char) 0xd7)
1687 size_t size
; /* Exact size requested by user. */
1688 unsigned long int magic
; /* Magic number to check header integrity. */
1691 static void checkhdr
__P ((__const
struct hdr
*));
1694 __const
struct hdr
*hdr
;
1696 if (hdr
->magic
!= MAGICWORD
|| ((char *) &hdr
[1])[hdr
->size
] != MAGICBYTE
)
1700 static void freehook
__P ((__ptr_t
));
1705 struct hdr
*hdr
= ((struct hdr
*) ptr
) - 1;
1708 __free_hook
= old_free_hook
;
1710 __free_hook
= freehook
;
1713 static __ptr_t mallochook
__P ((size_t));
1720 __malloc_hook
= old_malloc_hook
;
1721 hdr
= (struct hdr
*) malloc (sizeof (struct hdr
) + size
+ 1);
1722 __malloc_hook
= mallochook
;
1727 hdr
->magic
= MAGICWORD
;
1728 ((char *) &hdr
[1])[size
] = MAGICBYTE
;
1729 return (__ptr_t
) (hdr
+ 1);
1732 static __ptr_t reallochook
__P ((__ptr_t
, size_t));
1734 reallochook (ptr
, size
)
1738 struct hdr
*hdr
= ((struct hdr
*) ptr
) - 1;
1741 __free_hook
= old_free_hook
;
1742 __malloc_hook
= old_malloc_hook
;
1743 __realloc_hook
= old_realloc_hook
;
1744 hdr
= (struct hdr
*) realloc ((__ptr_t
) hdr
, sizeof (struct hdr
) + size
+ 1);
1745 __free_hook
= freehook
;
1746 __malloc_hook
= mallochook
;
1747 __realloc_hook
= reallochook
;
1752 ((char *) &hdr
[1])[size
] = MAGICBYTE
;
1753 return (__ptr_t
) (hdr
+ 1);
1758 void (*func
) __P ((void));
1760 extern void abort
__P ((void));
1761 static int mcheck_used
= 0;
1763 abortfunc
= (func
!= NULL
) ? func
: abort
;
1765 /* These hooks may not be safely inserted if malloc is already in use. */
1766 if (!__malloc_initialized
&& !mcheck_used
)
1768 old_free_hook
= __free_hook
;
1769 __free_hook
= freehook
;
1770 old_malloc_hook
= __malloc_hook
;
1771 __malloc_hook
= mallochook
;
1772 old_realloc_hook
= __realloc_hook
;
1773 __realloc_hook
= reallochook
;
1777 return mcheck_used
? 0 : -1;
1779 /* More debugging hooks for `malloc'.
1780 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1781 Written April 2, 1991 by John Gilmore of Cygnus Support.
1782 Based on mcheck.c by Mike Haertel.
1784 This library is free software; you can redistribute it and/or
1785 modify it under the terms of the GNU Library General Public License as
1786 published by the Free Software Foundation; either version 2 of the
1787 License, or (at your option) any later version.
1789 This library is distributed in the hope that it will be useful,
1790 but WITHOUT ANY WARRANTY; without even the implied warranty of
1791 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1792 Library General Public License for more details.
1794 You should have received a copy of the GNU Library General Public
1795 License along with this library; see the file COPYING.LIB. If
1796 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1797 Cambridge, MA 02139, USA.
1799 The author may be reached (Email) at the address mike@ai.mit.edu,
1800 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1802 #ifndef _MALLOC_INTERNAL
1803 #define _MALLOC_INTERNAL
1809 #ifndef __GNU_LIBRARY__
1810 extern char *getenv ();
1815 static FILE *mallstream
;
1816 static char mallenv
[]= "MALLOC_TRACE";
1817 static char mallbuf
[BUFSIZ
]; /* Buffer for the output. */
1819 /* Address to breakpoint on accesses to... */
1822 /* Old hook values. */
1823 static __ptr_t (*tr_old_morecore
) __P ((ptrdiff_t increment
));
1824 static __ptr_t (*tr_old_lesscore
) __P ((__ptr_t ptr
, ptrdiff_t increment
));
1825 static void (*tr_old_free_hook
) __P ((__ptr_t ptr
));
1826 static __ptr_t (*tr_old_malloc_hook
) __P ((size_t size
));
1827 static __ptr_t (*tr_old_realloc_hook
) __P ((__ptr_t ptr
, size_t size
));
1829 /* This function is called when the block being alloc'd, realloc'd, or
1830 freed has an address matching the variable "mallwatch". In a debugger,
1831 set "mallwatch" to the address of interest, then put a breakpoint on
1834 void tr_break
__P ((void));
1840 static void tr_freehook
__P ((__ptr_t
));
1845 fprintf (mallstream
, "- %p\n", ptr
); /* Be sure to print it first. */
1846 if (ptr
== mallwatch
)
1848 __free_hook
= tr_old_free_hook
;
1850 __free_hook
= tr_freehook
;
1853 static __ptr_t tr_morecore
__P ((ptrdiff_t));
1855 tr_morecore (increment
)
1856 ptrdiff_t increment
;
1860 __morecore
= tr_old_morecore
;
1861 p
= (__ptr_t
) (*__morecore
) (increment
);
1862 __morecore
= tr_morecore
;
1864 fprintf (mallstream
, "$ %p %d\n", p
, increment
);
1869 static __ptr_t tr_lesscore
__P ((__ptr_t
, ptrdiff_t));
1871 tr_lesscore (ptr
, increment
)
1873 ptrdiff_t increment
;
1877 __lesscore
= tr_old_lesscore
;
1878 p
= (__ptr_t
) (*__lesscore
) (ptr
, increment
);
1879 __lesscore
= tr_lesscore
;
1881 fprintf (mallstream
, "* %p (%p, %d)\n", p
, ptr
, increment
);
1886 static __ptr_t tr_mallochook
__P ((size_t));
1888 tr_mallochook (size
)
1893 __malloc_hook
= tr_old_malloc_hook
;
1894 hdr
= (__ptr_t
) malloc (size
);
1895 __malloc_hook
= tr_mallochook
;
1897 /* We could be printing a NULL here; that's OK. */
1898 fprintf (mallstream
, "+ %p %x\n", hdr
, size
);
1900 if (hdr
== mallwatch
)
1906 static __ptr_t tr_reallochook
__P ((__ptr_t
, size_t));
1908 tr_reallochook (ptr
, size
)
1914 if (ptr
== mallwatch
)
1917 __free_hook
= tr_old_free_hook
;
1918 __malloc_hook
= tr_old_malloc_hook
;
1919 __realloc_hook
= tr_old_realloc_hook
;
1920 hdr
= (__ptr_t
) realloc (ptr
, size
);
1921 __free_hook
= tr_freehook
;
1922 __malloc_hook
= tr_mallochook
;
1923 __realloc_hook
= tr_reallochook
;
1925 /* Failed realloc. */
1926 fprintf (mallstream
, "! %p %x\n", ptr
, size
);
1928 fprintf (mallstream
, "< %p\n> %p %x\n", ptr
, hdr
, size
);
1930 if (hdr
== mallwatch
)
1936 /* We enable tracing if either the environment variable MALLOC_TRACE
1937 is set, or if the variable mallwatch has been patched to an address
1938 that the debugging user wants us to stop on. When patching mallwatch,
1939 don't forget to set a breakpoint on tr_break! */
1946 mallfile
= getenv (mallenv
);
1947 if (mallfile
!= NULL
|| mallwatch
!= NULL
)
1949 mallstream
= fopen (mallfile
!= NULL
? mallfile
: "/dev/null", "w");
1950 if (mallstream
!= NULL
)
1952 /* Be sure it doesn't malloc its buffer! */
1953 setbuf (mallstream
, mallbuf
);
1954 fprintf (mallstream
, "= Start\n");
1955 #if defined(emacs) && defined(VMS)
1956 fprintf (mallstream
, "= Initial buffer spans %p -- %p\n",
1957 vms_initial_buffer
, vms_end_brk
+ 1);
1959 tr_old_morecore
= __morecore
;
1960 __morecore
= tr_morecore
;
1961 tr_old_lesscore
= __lesscore
;
1962 __lesscore
= tr_lesscore
;
1963 tr_old_free_hook
= __free_hook
;
1964 __free_hook
= tr_freehook
;
1965 tr_old_malloc_hook
= __malloc_hook
;
1966 __malloc_hook
= tr_mallochook
;
1967 tr_old_realloc_hook
= __realloc_hook
;
1968 __realloc_hook
= tr_reallochook
;
1972 /* Access the statistics maintained by `malloc'.
1973 Copyright 1990, 1991, 1992 Free Software Foundation
1974 Written May 1989 by Mike Haertel.
1976 This library is free software; you can redistribute it and/or
1977 modify it under the terms of the GNU Library General Public License as
1978 published by the Free Software Foundation; either version 2 of the
1979 License, or (at your option) any later version.
1981 This library is distributed in the hope that it will be useful,
1982 but WITHOUT ANY WARRANTY; without even the implied warranty of
1983 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1984 Library General Public License for more details.
1986 You should have received a copy of the GNU Library General Public
1987 License along with this library; see the file COPYING.LIB. If
1988 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1989 Cambridge, MA 02139, USA.
1991 The author may be reached (Email) at the address mike@ai.mit.edu,
1992 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1994 #ifndef _MALLOC_INTERNAL
1995 #define _MALLOC_INTERNAL
2002 struct mstats result
;
2004 result
.bytes_total
= (char *) (*__morecore
) (0) - _heapbase
;
2005 result
.chunks_used
= _chunks_used
;
2006 result
.bytes_used
= _bytes_used
;
2007 result
.chunks_free
= _chunks_free
;
2008 result
.bytes_free
= _bytes_free
;