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, 1999 Free Software Foundation, Inc.
9 Written May 1989 by Mike Haertel.
11 This file is part of GNU Emacs.
13 GNU Emacs is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2, or (at your option)
18 GNU Emacs is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with GNU Emacs; see the file COPYING. If not, write to
25 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
28 The author may be reached (Email) at the address mike@ai.mit.edu,
29 or (US mail) as Mike Haertel c/o Free Software Foundation. */
40 #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
42 #define __P(args) args
46 #define __ptr_t void *
47 #else /* Not C++ or ANSI C. */
53 #define __ptr_t char *
54 #endif /* C++ or ANSI C. */
60 #if defined (HAVE_CONFIG_H) || defined (emacs)
67 #ifdef VMS /* The following are defined in stdio.h, but we need it NOW!
68 But do NOT do it with defines here, for then, VAX C is going
69 to barf when it gets to stdio.h and the typedefs in there! */
70 typedef unsigned int size_t;
71 typedef int ptrdiff_t;
74 #define size_t unsigned int
81 /* Allocate SIZE bytes of memory. */
82 extern __ptr_t malloc
__P ((size_t __size
));
83 /* Re-allocate the previously allocated block
84 in __ptr_t, making the new block SIZE bytes long. */
85 extern __ptr_t realloc
__P ((__ptr_t __ptr
, size_t __size
));
86 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
87 extern __ptr_t calloc
__P ((size_t __nmemb
, size_t __size
));
88 /* Free a block allocated by `malloc', `realloc' or `calloc'. */
89 extern void free
__P ((__ptr_t __ptr
));
91 /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
92 extern __ptr_t memalign
__P ((size_t __alignment
, size_t __size
));
94 /* Allocate SIZE bytes on a page boundary. */
95 extern __ptr_t valloc
__P ((size_t __size
));
98 /* VMS hooks to deal with two heaps */
99 /* Allocate SIZE bytes of memory. */
100 extern __ptr_t __vms_malloc
__P ((size_t __size
));
101 /* Re-allocate the previously allocated block
102 in __ptr_t, making the new block SIZE bytes long. */
103 extern __ptr_t __vms_realloc
__P ((__ptr_t __ptr
, size_t __size
));
104 /* Free a block allocated by `malloc', `realloc' or `calloc'. */
105 extern void __vms_free
__P ((__ptr_t __ptr
));
108 #ifdef _MALLOC_INTERNAL
110 #include <stdio.h> /* Harmless, gets __GNU_LIBRARY__ defined. */
112 #if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) || defined(USG)
116 #define memset(s, zero, n) bzero ((s), (n))
119 #define memcpy(d, s, n) bcopy ((s), (d), (n))
122 #define memmove(d, s, n) bcopy ((s), (d), (n))
127 #if defined(__GNU_LIBRARY__) || defined(__STDC__)
133 /* The allocator divides the heap into blocks of fixed size; large
134 requests receive one or more whole blocks, and small requests
135 receive a fragment of a block. Fragment sizes are powers of two,
136 and all fragments of a block are the same size. When all the
137 fragments in a block have been freed, the block itself is freed. */
138 #define INT_BIT (CHAR_BIT * sizeof(int))
142 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
144 #define BLOCKSIZE (1 << BLOCKLOG)
145 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
147 /* Determine the amount of memory spanned by the initial heap table
148 (not an absolute limit). */
149 #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
151 /* Number of contiguous free blocks allowed to build up at the end of
152 memory before they will be returned to the system. */
153 #define FINAL_FREE_BLOCKS 8
155 /* Data structure giving per-block information. */
158 /* Heap information for a busy block. */
161 /* Zero for a large block, or positive giving the
162 logarithm to the base two of the fragment size. */
168 size_t nfree
; /* Free fragments in a fragmented block. */
169 size_t first
; /* First free fragment of the block. */
171 /* Size (in blocks) of a large cluster. */
175 /* Heap information for a free block
176 (that may be the first of a free cluster). */
179 size_t size
; /* Size (in blocks) of a free cluster. */
180 size_t next
; /* Index of next free cluster. */
181 size_t prev
; /* Index of previous free cluster. */
185 /* Pointer to first block of the heap. */
186 extern char *_heapbase
;
188 /* Table indexed by block number giving per-block information. */
189 extern malloc_info
*_heapinfo
;
191 /* Address to block number and vice versa. */
192 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
193 #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
195 /* Current search index for the heap table. */
196 extern size_t _heapindex
;
198 /* Limit of valid info table indices. */
199 extern size_t _heaplimit
;
201 /* Doubly linked lists of free fragments. */
208 /* Free list headers for each fragment size. */
209 extern struct list _fraghead
[];
211 /* List of blocks allocated with `memalign' (or `valloc'). */
214 struct alignlist
*next
;
215 __ptr_t aligned
; /* The address that memaligned returned. */
216 __ptr_t exact
; /* The address that malloc returned. */
218 extern struct alignlist
*_aligned_blocks
;
220 /* Instrumentation. */
221 extern size_t _chunks_used
;
222 extern size_t _bytes_used
;
223 extern size_t _chunks_free
;
224 extern size_t _bytes_free
;
226 /* Internal version of `free' used in `morecore' (malloc.c). */
227 extern void _free_internal
__P ((__ptr_t __ptr
));
229 #endif /* _MALLOC_INTERNAL. */
231 /* Underlying allocation function; successive calls should
232 return contiguous pieces of memory. */
233 /* It does NOT always return contiguous pieces of memory on VMS. */
234 extern __ptr_t (*__morecore
) __P ((ptrdiff_t __size
));
236 /* Underlying deallocation function. It accepts both a pointer and
237 a size to back up. It is implementation dependent what is really
239 extern __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
, ptrdiff_t __size
));
241 /* Default value of `__morecore'. */
242 extern __ptr_t __default_morecore
__P ((ptrdiff_t __size
));
244 /* Default value of `__lesscore'. */
245 extern __ptr_t __default_lesscore
__P ((__ptr_t __ptr
, ptrdiff_t __size
));
248 /* Default value of `__morecore'. */
249 extern __ptr_t __vms_morecore
__P ((ptrdiff_t __size
));
251 /* Default value of `__lesscore'. */
252 extern __ptr_t __vms_lesscore
__P ((__ptr_t __ptr
, ptrdiff_t __size
));
255 /* If not NULL, this function is called after each time
256 `__morecore' is called to increase the data size. */
257 extern void (*__after_morecore_hook
) __P ((void));
259 /* If not NULL, this function is called after each time
260 `__lesscore' is called to increase the data size. */
261 extern void (*__after_lesscore_hook
) __P ((void));
263 /* Nonzero if `malloc' has been called and done its initialization. */
264 extern int __malloc_initialized
;
266 /* Hooks for debugging versions. */
267 extern void (*__free_hook
) __P ((__ptr_t __ptr
));
268 extern __ptr_t (*__malloc_hook
) __P ((size_t __size
));
269 extern __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
));
271 /* Activate a standard collection of debugging hooks. */
272 extern int mcheck
__P ((void (*__func
) __P ((void))));
274 /* Activate a standard collection of tracing hooks. */
275 extern void mtrace
__P ((void));
277 /* Statistics available to the user. */
280 size_t bytes_total
; /* Total size of the heap. */
281 size_t chunks_used
; /* Chunks allocated by the user. */
282 size_t bytes_used
; /* Byte total of user-allocated chunks. */
283 size_t chunks_free
; /* Chunks in the free list. */
284 size_t bytes_free
; /* Byte total of chunks in the free list. */
287 /* Pick up the current statistics. */
288 extern struct mstats mstats
__P ((void));
290 /* Call WARNFUN with a warning message when memory usage is high. */
291 extern void memory_warnings
__P ((__ptr_t __start
,
292 void (*__warnfun
) __P ((__const
char *))));
295 /* Relocating allocator. */
297 /* Allocate SIZE bytes, and store the address in *HANDLEPTR. */
298 extern __ptr_t r_alloc
__P ((__ptr_t
*__handleptr
, size_t __size
));
300 /* Free the storage allocated in HANDLEPTR. */
301 extern void r_alloc_free
__P ((__ptr_t
*__handleptr
));
303 /* Adjust the block at HANDLEPTR to be SIZE bytes long. */
304 extern __ptr_t r_re_alloc
__P ((__ptr_t
*__handleptr
, size_t __size
));
311 #endif /* malloc.h */
312 /* Memory allocator `malloc'.
313 Copyright 1990, 1991, 1992, 1993 Free Software Foundation
314 Written May 1989 by Mike Haertel.
316 This library is free software; you can redistribute it and/or
317 modify it under the terms of the GNU Library General Public License as
318 published by the Free Software Foundation; either version 2 of the
319 License, or (at your option) any later version.
321 This library is distributed in the hope that it will be useful,
322 but WITHOUT ANY WARRANTY; without even the implied warranty of
323 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
324 Library General Public License for more details.
326 You should have received a copy of the GNU Library General Public
327 License along with this library; see the file COPYING.LIB. If
328 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
329 Cambridge, MA 02139, USA.
331 The author may be reached (Email) at the address mike@ai.mit.edu,
332 or (US mail) as Mike Haertel c/o Free Software Foundation. */
334 #ifndef _MALLOC_INTERNAL
335 #define _MALLOC_INTERNAL
340 /* How to really get more memory. */
341 __ptr_t (*__morecore
) __P ((ptrdiff_t __size
)) = __vms_morecore
;
343 /* How to really get more memory. */
344 __ptr_t (*__morecore
) __P ((ptrdiff_t __size
)) = __default_morecore
;
347 /* Debugging hook for `malloc'. */
349 __ptr_t (*__malloc_hook
) __P ((size_t __size
)) = __vms_malloc
;
351 __ptr_t (*__malloc_hook
) __P ((size_t __size
));
354 /* Pointer to the base of the first block. */
357 /* Block information table. Allocated with align/__free (not malloc/free). */
358 malloc_info
*_heapinfo
;
360 /* Number of info entries. */
361 static size_t heapsize
;
363 /* Search index in the info table. */
366 /* Limit of valid info table indices. */
369 /* Free lists for each fragment size. */
370 struct list _fraghead
[BLOCKLOG
];
372 /* Instrumentation. */
378 /* Are you experienced? */
379 int __malloc_initialized
;
381 void (*__after_morecore_hook
) __P ((void));
383 /* Aligned allocation. */
384 static __ptr_t align
__P ((size_t));
390 unsigned long int adj
;
392 result
= (*__morecore
) (size
);
393 adj
= (unsigned long int) ((unsigned long int) ((char *) result
-
394 (char *) NULL
)) % BLOCKSIZE
;
397 adj
= BLOCKSIZE
- adj
;
398 (void) (*__morecore
) (adj
);
399 result
= (char *) result
+ adj
;
402 if (__after_morecore_hook
)
403 (*__after_morecore_hook
) ();
408 /* Set everything up and remember that we have. */
409 static int initialize
__P ((void));
414 extern VMS_present_buffer();
415 printf("__malloc_initialized = %d\n", __malloc_initialized
);
416 VMS_present_buffer();
418 heapsize
= HEAP
/ BLOCKSIZE
;
419 _heapinfo
= (malloc_info
*) align (heapsize
* sizeof (malloc_info
));
420 if (_heapinfo
== NULL
)
422 memset (_heapinfo
, 0, heapsize
* sizeof (malloc_info
));
423 _heapinfo
[0].free
.size
= 0;
424 _heapinfo
[0].free
.next
= _heapinfo
[0].free
.prev
= 0;
426 _heapbase
= (char *) _heapinfo
;
429 printf("_heapbase = 0%o/0x%x/%d\n", _heapbase
, _heapbase
, _heapbase
);
432 __malloc_initialized
= 1;
436 /* Get neatly aligned memory, initializing or
437 growing the heap info table as necessary. */
438 static __ptr_t morecore
__P ((size_t));
444 malloc_info
*newinfo
, *oldinfo
;
447 result
= align (size
);
451 /* Check if we need to grow the info table. */
452 if ((size_t) BLOCK ((char *) result
+ size
) > heapsize
)
455 while ((size_t) BLOCK ((char *) result
+ size
) > newsize
)
457 newinfo
= (malloc_info
*) align (newsize
* sizeof (malloc_info
));
460 (*__lesscore
) (result
, size
);
463 memset (newinfo
, 0, newsize
* sizeof (malloc_info
));
464 memcpy (newinfo
, _heapinfo
, heapsize
* sizeof (malloc_info
));
466 newinfo
[BLOCK (oldinfo
)].busy
.type
= 0;
467 newinfo
[BLOCK (oldinfo
)].busy
.info
.size
468 = BLOCKIFY (heapsize
* sizeof (malloc_info
));
470 _free_internal (oldinfo
);
474 _heaplimit
= BLOCK ((char *) result
+ size
);
478 /* Allocate memory from the heap. */
484 size_t block
, blocks
, lastblocks
, start
;
491 if (__malloc_hook
!= NULL
)
492 return (*__malloc_hook
) (size
);
494 if (!__malloc_initialized
)
498 if (size
< sizeof (struct list
))
499 size
= sizeof (struct list
);
501 /* Determine the allocation policy based on the request size. */
502 if (size
<= BLOCKSIZE
/ 2)
504 /* Small allocation to receive a fragment of a block.
505 Determine the logarithm to base two of the fragment size. */
506 register size_t log
= 1;
508 while ((size
/= 2) != 0)
511 /* Look in the fragment lists for a
512 free fragment of the desired size. */
513 next
= _fraghead
[log
].next
;
516 /* There are free fragments of this size.
517 Pop a fragment out of the fragment list and return it.
518 Update the block's nfree and first counters. */
519 result
= (__ptr_t
) next
;
520 next
->prev
->next
= next
->next
;
521 if (next
->next
!= NULL
)
522 next
->next
->prev
= next
->prev
;
523 block
= BLOCK (result
);
524 if (--_heapinfo
[block
].busy
.info
.frag
.nfree
!= 0)
525 _heapinfo
[block
].busy
.info
.frag
.first
= (unsigned long int)
526 ((unsigned long int) ((char *) next
->next
- (char *) NULL
)
529 /* Update the statistics. */
531 _bytes_used
+= 1 << log
;
533 _bytes_free
-= 1 << log
;
537 /* No free fragments of the desired size, so get a new block
538 and break it into fragments, returning the first. */
539 result
= malloc (BLOCKSIZE
);
543 /* Link all fragments but the first into the free list. */
544 for (i
= 1; i
< (size_t) (BLOCKSIZE
>> log
); ++i
)
546 next
= (struct list
*) ((char *) result
+ (i
<< log
));
548 printf("DEBUG: malloc (%d): next = %p\n", size
, next
);
550 next
->next
= _fraghead
[log
].next
;
551 next
->prev
= &_fraghead
[log
];
552 next
->prev
->next
= next
;
553 if (next
->next
!= NULL
)
554 next
->next
->prev
= next
;
557 /* Initialize the nfree and first counters for this block. */
558 block
= BLOCK (result
);
559 _heapinfo
[block
].busy
.type
= log
;
560 _heapinfo
[block
].busy
.info
.frag
.nfree
= i
- 1;
561 _heapinfo
[block
].busy
.info
.frag
.first
= i
- 1;
563 _chunks_free
+= (BLOCKSIZE
>> log
) - 1;
564 _bytes_free
+= BLOCKSIZE
- (1 << log
);
565 _bytes_used
-= BLOCKSIZE
- (1 << log
);
570 /* Large allocation to receive one or more blocks.
571 Search the free list in a circle starting at the last place visited.
572 If we loop completely around without finding a large enough
573 space we will have to get more memory from the system. */
574 blocks
= BLOCKIFY (size
);
575 start
= block
= _heapindex
;
576 while (_heapinfo
[block
].free
.size
< blocks
)
578 block
= _heapinfo
[block
].free
.next
;
581 /* Need to get more from the system. Check to see if
582 the new core will be contiguous with the final free
583 block; if so we don't need to get as much. */
584 block
= _heapinfo
[0].free
.prev
;
585 lastblocks
= _heapinfo
[block
].free
.size
;
586 if (_heaplimit
!= 0 && block
+ lastblocks
== _heaplimit
&&
587 (*__morecore
) (0) == ADDRESS (block
+ lastblocks
) &&
588 (morecore ((blocks
- lastblocks
) * BLOCKSIZE
)) != NULL
)
590 _heapinfo
[block
].free
.size
= blocks
;
591 _bytes_free
+= (blocks
- lastblocks
) * BLOCKSIZE
;
594 result
= morecore (blocks
* BLOCKSIZE
);
597 block
= BLOCK (result
);
598 _heapinfo
[block
].busy
.type
= 0;
599 _heapinfo
[block
].busy
.info
.size
= blocks
;
601 _bytes_used
+= blocks
* BLOCKSIZE
;
606 /* At this point we have found a suitable free list entry.
607 Figure out how to remove what we need from the list. */
608 result
= ADDRESS (block
);
609 if (_heapinfo
[block
].free
.size
> blocks
)
611 /* The block we found has a bit left over,
612 so relink the tail end back into the free list. */
613 _heapinfo
[block
+ blocks
].free
.size
614 = _heapinfo
[block
].free
.size
- blocks
;
615 _heapinfo
[block
+ blocks
].free
.next
616 = _heapinfo
[block
].free
.next
;
617 _heapinfo
[block
+ blocks
].free
.prev
618 = _heapinfo
[block
].free
.prev
;
619 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
620 = _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
621 = _heapindex
= block
+ blocks
;
625 /* The block exactly matches our requirements,
626 so just remove it from the list. */
627 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
628 = _heapinfo
[block
].free
.prev
;
629 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
630 = _heapindex
= _heapinfo
[block
].free
.next
;
634 _heapinfo
[block
].busy
.type
= 0;
635 _heapinfo
[block
].busy
.info
.size
= blocks
;
637 _bytes_used
+= blocks
* BLOCKSIZE
;
638 _bytes_free
-= blocks
* BLOCKSIZE
;
643 /* Free a block of memory allocated by `malloc'.
644 Copyright 1990, 1991, 1992 Free Software Foundation
645 Written May 1989 by Mike Haertel.
647 This library is free software; you can redistribute it and/or
648 modify it under the terms of the GNU Library General Public License as
649 published by the Free Software Foundation; either version 2 of the
650 License, or (at your option) any later version.
652 This library is distributed in the hope that it will be useful,
653 but WITHOUT ANY WARRANTY; without even the implied warranty of
654 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
655 Library General Public License for more details.
657 You should have received a copy of the GNU Library General Public
658 License along with this library; see the file COPYING.LIB. If
659 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
660 Cambridge, MA 02139, USA.
662 The author may be reached (Email) at the address mike@ai.mit.edu,
663 or (US mail) as Mike Haertel c/o Free Software Foundation. */
665 #ifndef _MALLOC_INTERNAL
666 #define _MALLOC_INTERNAL
671 /* How to really get more memory. */
672 __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
,ptrdiff_t __size
)) = __vms_lesscore
;
674 /* How to really get more memory. */
675 __ptr_t (*__lesscore
) __P ((__ptr_t __ptr
,ptrdiff_t __size
)) = __default_lesscore
;
678 /* Debugging hook for free. */
680 void (*__free_hook
) __P ((__ptr_t __ptr
)) = __vms_free
;
682 void (*__free_hook
) __P ((__ptr_t __ptr
));
685 /* List of blocks allocated by memalign. */
686 struct alignlist
*_aligned_blocks
= NULL
;
688 /* Return memory to the heap.
689 Like `free' but don't call a __free_hook if there is one. */
695 size_t block
, blocks
;
697 struct list
*prev
, *next
;
701 type
= _heapinfo
[block
].busy
.type
;
705 /* Get as many statistics as early as we can. */
707 _bytes_used
-= _heapinfo
[block
].busy
.info
.size
* BLOCKSIZE
;
708 _bytes_free
+= _heapinfo
[block
].busy
.info
.size
* BLOCKSIZE
;
710 /* Find the free cluster previous to this one in the free list.
711 Start searching at the last block referenced; this may benefit
712 programs with locality of allocation. */
716 i
= _heapinfo
[i
].free
.prev
;
720 i
= _heapinfo
[i
].free
.next
;
721 while (i
> 0 && i
< block
);
722 i
= _heapinfo
[i
].free
.prev
;
725 /* Determine how to link this block into the free list. */
726 if (block
== i
+ _heapinfo
[i
].free
.size
)
728 /* Coalesce this block with its predecessor. */
729 _heapinfo
[i
].free
.size
+= _heapinfo
[block
].busy
.info
.size
;
734 /* Really link this block back into the free list. */
735 _heapinfo
[block
].free
.size
= _heapinfo
[block
].busy
.info
.size
;
736 _heapinfo
[block
].free
.next
= _heapinfo
[i
].free
.next
;
737 _heapinfo
[block
].free
.prev
= i
;
738 _heapinfo
[i
].free
.next
= block
;
739 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
= block
;
743 /* Now that the block is linked in, see if we can coalesce it
744 with its successor (by deleting its successor from the list
745 and adding in its size). */
746 if (block
+ _heapinfo
[block
].free
.size
== _heapinfo
[block
].free
.next
)
748 _heapinfo
[block
].free
.size
749 += _heapinfo
[_heapinfo
[block
].free
.next
].free
.size
;
750 _heapinfo
[block
].free
.next
751 = _heapinfo
[_heapinfo
[block
].free
.next
].free
.next
;
752 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
= block
;
756 /* Now see if we can return stuff to the system. */
757 blocks
= _heapinfo
[block
].free
.size
;
758 if (blocks
>= FINAL_FREE_BLOCKS
&& block
+ blocks
== _heaplimit
759 && (*__morecore
) (0) == ADDRESS (block
+ blocks
))
761 register size_t bytes
= blocks
* BLOCKSIZE
;
762 _heaplimit
-= blocks
;
763 (*__lesscore
) (ADDRESS(block
), bytes
);
764 _heapinfo
[_heapinfo
[block
].free
.prev
].free
.next
765 = _heapinfo
[block
].free
.next
;
766 _heapinfo
[_heapinfo
[block
].free
.next
].free
.prev
767 = _heapinfo
[block
].free
.prev
;
768 block
= _heapinfo
[block
].free
.prev
;
770 _bytes_free
-= bytes
;
773 /* Set the next search to begin at this block. */
778 /* Do some of the statistics. */
780 _bytes_used
-= 1 << type
;
782 _bytes_free
+= 1 << type
;
784 /* Get the address of the first free fragment in this block. */
785 prev
= (struct list
*) ((char *) ADDRESS (block
) +
786 (_heapinfo
[block
].busy
.info
.frag
.first
<< type
));
788 printf("_free_internal(0%o/0x%x/%d) :\n", ptr
, ptr
, ptr
);
789 printf(" block = %d, type = %d, prev = 0%o/0x%x/%d\n",
790 block
, type
, prev
, prev
, prev
);
791 printf(" _heapinfo[block=%d].busy.info.frag.nfree = %d\n",
793 _heapinfo
[block
].busy
.info
.frag
.nfree
);
796 if (_heapinfo
[block
].busy
.info
.frag
.nfree
== (BLOCKSIZE
>> type
) - 1)
798 /* If all fragments of this block are free, remove them
799 from the fragment list and free the whole block. */
801 for (i
= 1; i
< (size_t) (BLOCKSIZE
>> type
); ++i
)
803 prev
->prev
->next
= next
;
805 next
->prev
= prev
->prev
;
806 _heapinfo
[block
].busy
.type
= 0;
807 _heapinfo
[block
].busy
.info
.size
= 1;
809 /* Keep the statistics accurate. */
811 _bytes_used
+= BLOCKSIZE
;
812 _chunks_free
-= BLOCKSIZE
>> type
;
813 _bytes_free
-= BLOCKSIZE
;
815 free (ADDRESS (block
));
817 else if (_heapinfo
[block
].busy
.info
.frag
.nfree
!= 0)
819 /* If some fragments of this block are free, link this
820 fragment into the fragment list after the first free
821 fragment of this block. */
823 printf("There's a bug hiding here (%s:%d), so I will print some values\n", __FILE__
, __LINE__
);
825 next
= (struct list
*) ptr
;
827 printf(" (struct list *)next (0%o / 0x%x / %d) ->\n", next
, next
, next
);
828 printf(" next = 0%o / 0x%x / %d\n", next
->next
,next
->next
,next
->next
);
829 printf(" prev = 0%o / 0x%x / %d\n", next
->prev
,next
->prev
,next
->prev
);
830 printf(" (struct list *)prev (0%o / 0x%x / %d)->\n", prev
, prev
, prev
);
831 printf(" next = 0%o / 0x%x / %d\n", prev
->next
,prev
->next
,prev
->next
);
832 printf(" prev = 0%o / 0x%x / %d\n", prev
->prev
,prev
->prev
,prev
->prev
);
834 next
->next
= prev
->next
;
837 if (next
->next
!= NULL
)
838 next
->next
->prev
= next
;
839 ++_heapinfo
[block
].busy
.info
.frag
.nfree
;
843 /* No fragments of this block are free, so link this
844 fragment into the fragment list and announce that
845 it is the first free fragment of this block. */
846 prev
= (struct list
*) ptr
;
847 _heapinfo
[block
].busy
.info
.frag
.nfree
= 1;
848 _heapinfo
[block
].busy
.info
.frag
.first
= (unsigned long int)
849 ((unsigned long int) ((char *) ptr
- (char *) NULL
)
850 % BLOCKSIZE
>> type
);
851 prev
->next
= _fraghead
[type
].next
;
852 prev
->prev
= &_fraghead
[type
];
853 prev
->prev
->next
= prev
;
854 if (prev
->next
!= NULL
)
855 prev
->next
->prev
= prev
;
861 /* Return memory to the heap. */
866 register struct alignlist
*l
;
871 for (l
= _aligned_blocks
; l
!= NULL
; l
= l
->next
)
872 if (l
->aligned
== ptr
)
874 l
->aligned
= NULL
; /* Mark the slot in the list as free. */
879 if (__free_hook
!= NULL
)
880 (*__free_hook
) (ptr
);
882 _free_internal (ptr
);
884 /* Change the size of a block allocated by `malloc'.
885 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
886 Written May 1989 by Mike Haertel.
888 This library is free software; you can redistribute it and/or
889 modify it under the terms of the GNU Library General Public License as
890 published by the Free Software Foundation; either version 2 of the
891 License, or (at your option) any later version.
893 This library is distributed in the hope that it will be useful,
894 but WITHOUT ANY WARRANTY; without even the implied warranty of
895 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
896 Library General Public License for more details.
898 You should have received a copy of the GNU Library General Public
899 License along with this library; see the file COPYING.LIB. If
900 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
901 Cambridge, MA 02139, USA.
903 The author may be reached (Email) at the address mike@ai.mit.edu,
904 or (US mail) as Mike Haertel c/o Free Software Foundation. */
906 #ifndef _MALLOC_INTERNAL
907 #define _MALLOC_INTERNAL
911 #define min(A, B) ((A) < (B) ? (A) : (B))
913 /* Debugging hook for realloc. */
915 __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
)) = __vms_realloc
;
917 __ptr_t (*__realloc_hook
) __P ((__ptr_t __ptr
, size_t __size
));
920 /* Resize the given region to the new size, returning a pointer
921 to the (possibly moved) region. This is optimized for speed;
922 some benchmarks seem to indicate that greater compactness is
923 achieved by unconditionally allocating and copying to a
924 new region. This module has incestuous knowledge of the
925 internals of both free and malloc. */
933 size_t block
, blocks
, oldlimit
;
940 else if (ptr
== NULL
)
941 return malloc (size
);
943 if (__realloc_hook
!= NULL
)
944 return (*__realloc_hook
) (ptr
, size
);
948 type
= _heapinfo
[block
].busy
.type
;
952 /* Maybe reallocate a large block to a small fragment. */
953 if (size
<= BLOCKSIZE
/ 2)
955 result
= malloc (size
);
958 memcpy (result
, ptr
, size
);
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
)
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
));
978 else if (blocks
== _heapinfo
[block
].busy
.info
.size
)
979 /* No size change necessary. */
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
;
991 _heaplimit
= oldlimit
;
992 result
= malloc (size
);
995 /* Now we're really in trouble. We have to unfree
996 the thing we just freed. Unfortunately it might
997 have been coalesced with its neighbors. */
998 if (_heapindex
== block
)
999 (void) malloc (blocks
* BLOCKSIZE
);
1002 __ptr_t previous
= malloc ((block
- _heapindex
) * BLOCKSIZE
);
1003 (void) malloc (blocks
* BLOCKSIZE
);
1009 memmove (result
, ptr
, blocks
* BLOCKSIZE
);
1014 /* Old size is a fragment; type is logarithm
1015 to base two of the fragment size. */
1016 if (size
> (size_t) (1 << (type
- 1)) && size
<= (size_t) (1 << type
))
1017 /* The new size is the same kind of fragment. */
1021 /* The new size is different; allocate a new space,
1022 and copy the lesser of the new size and the old. */
1023 result
= malloc (size
);
1026 memcpy (result
, ptr
, min (size
, (size_t) 1 << type
));
1034 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1036 This library is free software; you can redistribute it and/or
1037 modify it under the terms of the GNU Library General Public License as
1038 published by the Free Software Foundation; either version 2 of the
1039 License, or (at your option) any later version.
1041 This library is distributed in the hope that it will be useful,
1042 but WITHOUT ANY WARRANTY; without even the implied warranty of
1043 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1044 Library General Public License for more details.
1046 You should have received a copy of the GNU Library General Public
1047 License along with this library; see the file COPYING.LIB. If
1048 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1049 Cambridge, MA 02139, USA.
1051 The author may be reached (Email) at the address mike@ai.mit.edu,
1052 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1054 #ifndef _MALLOC_INTERNAL
1055 #define _MALLOC_INTERNAL
1059 /* Allocate an array of NMEMB elements each SIZE bytes long.
1060 The entire array is initialized to zeros. */
1062 calloc (nmemb
, size
)
1063 register size_t nmemb
;
1064 register size_t size
;
1066 register __ptr_t result
= malloc (nmemb
* size
);
1069 (void) memset (result
, 0, nmemb
* size
);
1073 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1074 This file is part of the GNU C Library.
1076 The GNU C Library is free software; you can redistribute it and/or modify
1077 it under the terms of the GNU General Public License as published by
1078 the Free Software Foundation; either version 2, or (at your option)
1081 The GNU C Library is distributed in the hope that it will be useful,
1082 but WITHOUT ANY WARRANTY; without even the implied warranty of
1083 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1084 GNU General Public License for more details.
1086 You should have received a copy of the GNU General Public License
1087 along with the GNU C Library; see the file COPYING. If not, write to
1088 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
1090 #ifndef _MALLOC_INTERNAL
1091 #define _MALLOC_INTERNAL
1095 #ifndef __GNU_LIBRARY__
1102 extern __ptr_t __sbrk
__P ((int increment
));
1108 #if defined(emacs) && defined(VMS)
1109 /* Dumping of Emacs on VMS does not include the heap!
1110 So let's make a huge array from which initial data will be
1113 VMS_ALLOCATION_SIZE is the amount of memory we preallocate.
1114 We don't want it to be too large, because it only gives a larger
1115 dump file. The way to check how much is really used is to
1116 make VMS_ALLOCATION_SIZE very large, to link Emacs with the
1117 debugger, run Emacs, check how much was allocated. Then set
1118 VMS_ALLOCATION_SIZE to something suitable, recompile gmalloc,
1119 relink Emacs, and you should be off.
1121 N.B. This is experimental, but it worked quite fine on Emacs 18.
1123 #ifndef VMS_ALLOCATION_SIZE
1124 #define VMS_ALLOCATION_SIZE (512*(512+128))
1127 int vms_out_initial
= 0;
1128 char vms_initial_buffer
[VMS_ALLOCATION_SIZE
];
1129 char *vms_current_brk
= vms_initial_buffer
;
1130 char *vms_end_brk
= &vms_initial_buffer
[VMS_ALLOCATION_SIZE
-1];
1133 __vms_initial_morecore (increment
)
1134 ptrdiff_t increment
;
1136 __ptr_t result
= NULL
;
1139 /* It's far easier to make the alignment here than to make a
1140 kludge in align () */
1142 printf(">>>foo... %p...", vms_current_brk
);
1144 vms_current_brk
+= (BLOCKSIZE
- ((unsigned long) vms_current_brk
1145 & (BLOCKSIZE
- 1))) & (BLOCKSIZE
- 1);
1147 printf("bar... %p. (%d)\n", vms_current_brk
, increment
);
1149 temp
= vms_current_brk
+ (int) increment
;
1150 if (temp
<= vms_end_brk
)
1153 result
= vms_current_brk
;
1156 vms_current_brk
= temp
;
1162 __vms_initial_lesscore (ptr
, size
)
1166 if (ptr
>= vms_initial_buffer
1167 && ptr
< vms_initial_buffer
+VMS_ALLOCATION_SIZE
)
1169 vms_current_brk
= ptr
;
1170 return vms_current_brk
;
1172 return vms_current_brk
;
1175 VMS_present_buffer()
1177 printf("Vms initial buffer starts at 0%o/0x%x/%d and ends at 0%o/0x%x/%d\n",
1178 vms_initial_buffer
, vms_initial_buffer
, vms_initial_buffer
,
1179 vms_end_brk
, vms_end_brk
, vms_end_brk
);
1181 #endif /* defined(emacs) && defined(VMS) */
1184 /* Unfortunately, the VAX C sbrk() is buggy. For example, it returns
1185 memory in 512 byte chunks (not a bug, but there's more), AND it
1186 adds an extra 512 byte chunk if you ask for a multiple of 512
1187 bytes (you ask for 512 bytes, you get 1024 bytes...). And also,
1188 the VAX C sbrk does not handle negative increments...
1189 There's a similar problem with brk(). Even if you set the break
1190 to an even page boundary, it gives you one extra page... */
1192 static char vms_brk_info_fetched
= -1; /* -1 if this is the first time, otherwise
1193 bit 0 set if 'increment' needs adjustment
1194 bit 1 set if the value to brk() needs adjustment */
1195 static char *vms_brk_start
= 0;
1196 static char *vms_brk_end
= 0;
1197 static char *vms_brk_current
= 0;
1200 /* Allocate INCREMENT more bytes of data space,
1201 and return the start of data space, or NULL on errors.
1202 If INCREMENT is negative, shrink data space. */
1204 __default_morecore (increment
)
1205 ptrdiff_t increment
;
1212 printf("DEBUG: morecore: increment = %x\n", increment
);
1213 printf(" @ start: vms_brk_info_fetched = %x\n", vms_brk_info_fetched
);
1214 printf(" vms_brk_start = %p\n", vms_brk_start
);
1215 printf(" vms_brk_current = %p\n", vms_brk_current
);
1216 printf(" vms_brk_end = %p\n", vms_brk_end
);
1220 if (vms_brk_info_fetched
< 0)
1222 vms_brk_current
= vms_brk_start
= __sbrk (512);
1223 vms_brk_end
= __sbrk (0);
1224 if (vms_brk_end
- vms_brk_current
== 1024)
1225 vms_brk_info_fetched
= 1;
1227 vms_brk_info_fetched
= 0;
1228 vms_brk_end
= brk(vms_brk_start
);
1229 if (vms_brk_end
!= vms_brk_start
)
1230 vms_brk_info_fetched
|= 2;
1232 printf("vms_brk_info_fetched = %x\n", vms_brk_info_fetched
);
1233 printf(" vms_brk_start = %p\n", vms_brk_start
);
1234 printf(" vms_brk_current = %p\n", vms_brk_current
);
1235 printf(" vms_brk_end = %p\n", vms_brk_end
);
1242 printf("BZZZZZT! ERROR: __default_morecore does NOT take negative args\n");
1248 result
= vms_brk_current
;
1249 temp
= vms_brk_current
+ increment
;
1251 if (temp
> vms_brk_end
)
1256 if (foo
== vms_brk_end
)
1258 increment
= temp
- vms_brk_end
;
1259 if (increment
> (vms_brk_info_fetched
& 1))
1260 increment
-= (vms_brk_info_fetched
& 1);
1261 foo
= __sbrk(increment
);
1263 printf("__sbrk(%d) --> %p\n", increment
, foo
);
1265 if (foo
== (__ptr_t
) -1)
1273 result
= __sbrk (increment
);
1275 if (result
== (__ptr_t
) -1)
1278 temp
= result
+ increment
;
1281 vms_brk_end
= __sbrk(0);
1283 vms_brk_current
= temp
;
1285 printf("vms_brk_current = %p\n", vms_brk_current
);
1286 printf(" vms_brk_end = %p\n", vms_brk_end
);
1291 printf(" nothing more...\n");
1294 /* OK, so the user wanted to check where the heap limit is. Let's
1295 see if the system thinks it is where we think it is. */
1297 if (temp
!= vms_brk_end
)
1299 /* the value has changed.
1300 Let's trust the system and modify our value */
1301 vms_brk_current
= vms_brk_end
= temp
;
1303 return vms_brk_current
;
1306 result
= __sbrk ((int) increment
);
1307 if (result
== (__ptr_t
) -1)
1314 __default_lesscore (ptr
, size
)
1319 if (vms_brk_end
!= 0)
1321 vms_brk_current
= ptr
;
1322 if (vms_brk_current
< vms_brk_start
)
1323 vms_brk_current
= vms_brk_start
;
1324 vms_brk_end
= (char *) vms_brk_current
-
1325 ((vms_brk_info_fetched
>> 1) & 1);
1327 printf("<<<bar... %p (%p (%p, %d))...",
1328 vms_brk_end
, vms_brk_current
, ptr
, size
);
1330 vms_brk_end
= __brk (vms_brk_end
);
1332 printf("foo... %p.\n", vms_brk_end
);
1336 return vms_brk_current
;
1338 __default_morecore (-size
);
1342 /* Allocate memory on a page boundary.
1343 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1345 This library is free software; you can redistribute it and/or
1346 modify it under the terms of the GNU Library General Public License as
1347 published by the Free Software Foundation; either version 2 of the
1348 License, or (at your option) any later version.
1350 This library is distributed in the hope that it will be useful,
1351 but WITHOUT ANY WARRANTY; without even the implied warranty of
1352 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1353 Library General Public License for more details.
1355 You should have received a copy of the GNU Library General Public
1356 License along with this library; see the file COPYING.LIB. If
1357 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1358 Cambridge, MA 02139, USA.
1360 The author may be reached (Email) at the address mike@ai.mit.edu,
1361 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1363 #ifndef _MALLOC_INTERNAL
1364 #define _MALLOC_INTERNAL
1368 #if defined (emacs) || defined (HAVE_CONFIG_H)
1372 #ifdef __GNU_LIBRARY__
1373 extern size_t __getpagesize
__P ((void));
1375 #if !defined(USG) && !defined(VMS)
1376 extern size_t getpagesize
__P ((void));
1377 #define __getpagesize() getpagesize()
1379 #include <sys/param.h>
1380 #ifdef EXEC_PAGESIZE
1381 #define __getpagesize() EXEC_PAGESIZE
1382 #else /* No EXEC_PAGESIZE. */
1386 #endif /* No CLSIZE. */
1387 #define __getpagesize() (NBPG * CLSIZE)
1388 #else /* No NBPG. */
1389 #define __getpagesize() NBPC
1391 #endif /* EXEC_PAGESIZE. */
1395 static size_t pagesize
;
1402 pagesize
= __getpagesize ();
1404 return memalign (pagesize
, size
);
1406 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1408 This library is free software; you can redistribute it and/or
1409 modify it under the terms of the GNU Library General Public License as
1410 published by the Free Software Foundation; either version 2 of the
1411 License, or (at your option) any later version.
1413 This library is distributed in the hope that it will be useful,
1414 but WITHOUT ANY WARRANTY; without even the implied warranty of
1415 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1416 Library General Public License for more details.
1418 You should have received a copy of the GNU Library General Public
1419 License along with this library; see the file COPYING.LIB. If
1420 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1421 Cambridge, MA 02139, USA. */
1423 #ifndef _MALLOC_INTERNAL
1424 #define _MALLOC_INTERNAL
1429 memalign (alignment
, size
)
1434 unsigned long int adj
;
1436 size
= ((size
+ alignment
- 1) / alignment
) * alignment
;
1438 result
= malloc (size
);
1441 adj
= (unsigned long int) ((unsigned long int) ((char *) result
-
1442 (char *) NULL
)) % alignment
;
1445 struct alignlist
*l
;
1446 for (l
= _aligned_blocks
; l
!= NULL
; l
= l
->next
)
1447 if (l
->aligned
== NULL
)
1448 /* This slot is free. Use it. */
1452 l
= (struct alignlist
*) malloc (sizeof (struct alignlist
));
1460 result
= l
->aligned
= (char *) result
+ alignment
- adj
;
1461 l
->next
= _aligned_blocks
;
1462 _aligned_blocks
= l
;
1469 struct vms_malloc_data
1471 int __malloc_initialized
;
1473 malloc_info
*_heapinfo
;
1477 size_t _chunks_used
;
1479 size_t _chunks_free
;
1481 } ____vms_malloc_data
[] =
1483 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1484 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1487 struct vms_core_routines
1489 __ptr_t (*__morecore
) __P ((ptrdiff_t increment
));
1490 __ptr_t (*__lesscore
) __P ((__ptr_t address
, ptrdiff_t increment
));
1491 } ____vms_core_routines
[] =
1493 { __vms_initial_morecore
, __vms_initial_lesscore
},
1494 { __default_morecore
, __default_lesscore
},
1498 static int current_vms_data
= -1;
1499 static int current_vms_core_routines
= 0;
1501 static void use_vms_core_routines (int i
)
1503 current_vms_core_routines
= i
;
1504 current_vms_data
= i
;
1507 static void use_vms_data (int i
)
1509 use_vms_core_routines (i
);
1510 __malloc_initialized
= ____vms_malloc_data
[i
].__malloc_initialized
;
1511 _heapbase
= ____vms_malloc_data
[i
]._heapbase
;
1512 _heapinfo
= ____vms_malloc_data
[i
]._heapinfo
;
1513 heapsize
= ____vms_malloc_data
[i
].heapsize
;
1514 _heapindex
= ____vms_malloc_data
[i
]._heapindex
;
1515 _heaplimit
= ____vms_malloc_data
[i
]._heaplimit
;
1516 _chunks_used
= ____vms_malloc_data
[i
]._chunks_used
;
1517 _bytes_used
= ____vms_malloc_data
[i
]._bytes_used
;
1518 _chunks_free
= ____vms_malloc_data
[i
]._chunks_free
;
1519 _bytes_free
= ____vms_malloc_data
[i
]._bytes_free
;
1522 static void store_vms_data (int i
)
1524 ____vms_malloc_data
[i
].__malloc_initialized
= __malloc_initialized
;
1525 ____vms_malloc_data
[i
]._heapbase
= _heapbase
;
1526 ____vms_malloc_data
[i
]._heapinfo
= _heapinfo
;
1527 ____vms_malloc_data
[i
].heapsize
= heapsize
;
1528 ____vms_malloc_data
[i
]._heapindex
= _heapindex
;
1529 ____vms_malloc_data
[i
]._heaplimit
= _heaplimit
;
1530 ____vms_malloc_data
[i
]._chunks_used
= _chunks_used
;
1531 ____vms_malloc_data
[i
]._bytes_used
= _bytes_used
;
1532 ____vms_malloc_data
[i
]._chunks_free
= _chunks_free
;
1533 ____vms_malloc_data
[i
]._bytes_free
= _bytes_free
;
1536 static void store_current_vms_data ()
1538 switch (current_vms_data
)
1542 store_vms_data (current_vms_data
);
1547 __ptr_t
__vms_morecore (increment
)
1548 ptrdiff_t increment
;
1551 (*____vms_core_routines
[current_vms_core_routines
].__morecore
) (increment
);
1554 __ptr_t
__vms_lesscore (ptr
, increment
)
1556 ptrdiff_t increment
;
1559 (*____vms_core_routines
[current_vms_core_routines
].__lesscore
) (ptr
,increment
);
1562 __ptr_t
__vms_malloc (size
)
1566 int old_current_vms_data
= current_vms_data
;
1570 store_current_vms_data ();
1572 if (____vms_malloc_data
[0]._heapbase
!= 0)
1575 use_vms_core_routines (0);
1576 result
= malloc (size
);
1581 result
= malloc (size
);
1583 vms_out_initial
= 1;
1585 __malloc_hook
= __vms_malloc
;
1586 if (old_current_vms_data
!= -1)
1587 use_vms_data (current_vms_data
);
1591 void __vms_free (ptr
)
1594 int old_current_vms_data
= current_vms_data
;
1598 store_current_vms_data ();
1600 if (ptr
>= vms_initial_buffer
&& ptr
<= vms_end_brk
)
1611 if (_chunks_free
== 0 && _chunks_used
== 0)
1612 vms_out_initial
= 0;
1614 __free_hook
= __vms_free
;
1615 if (old_current_vms_data
!= -1)
1616 use_vms_data (current_vms_data
);
1619 __ptr_t
__vms_realloc (ptr
, size
)
1624 int old_current_vms_data
= current_vms_data
;
1628 store_current_vms_data ();
1630 if (ptr
>= vms_initial_buffer
&& ptr
<= vms_end_brk
)
1633 result
= realloc (ptr
, size
);
1639 result
= realloc (ptr
, size
);
1642 __realloc_hook
= __vms_realloc
;
1643 if (old_current_vms_data
!= -1)
1644 use_vms_data (current_vms_data
);
1648 /* Standard debugging hooks for `malloc'.
1649 Copyright 1990, 1991, 1992 Free Software Foundation
1650 Written May 1989 by Mike Haertel.
1652 This library is free software; you can redistribute it and/or
1653 modify it under the terms of the GNU Library General Public License as
1654 published by the Free Software Foundation; either version 2 of the
1655 License, or (at your option) any later version.
1657 This library is distributed in the hope that it will be useful,
1658 but WITHOUT ANY WARRANTY; without even the implied warranty of
1659 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1660 Library General Public License for more details.
1662 You should have received a copy of the GNU Library General Public
1663 License along with this library; see the file COPYING.LIB. If
1664 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1665 Cambridge, MA 02139, USA.
1667 The author may be reached (Email) at the address mike@ai.mit.edu,
1668 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1670 #ifndef _MALLOC_INTERNAL
1671 #define _MALLOC_INTERNAL
1675 /* Old hook values. */
1676 static void (*old_free_hook
) __P ((__ptr_t ptr
));
1677 static __ptr_t (*old_malloc_hook
) __P ((size_t size
));
1678 static __ptr_t (*old_realloc_hook
) __P ((__ptr_t ptr
, size_t size
));
1680 /* Function to call when something awful happens. */
1681 static void (*abortfunc
) __P ((void));
1683 /* Arbitrary magical numbers. */
1684 #define MAGICWORD 0xfedabeeb
1685 #define MAGICBYTE ((char) 0xd7)
1689 size_t size
; /* Exact size requested by user. */
1690 unsigned long int magic
; /* Magic number to check header integrity. */
1693 static void checkhdr
__P ((__const
struct hdr
*));
1696 __const
struct hdr
*hdr
;
1698 if (hdr
->magic
!= MAGICWORD
|| ((char *) &hdr
[1])[hdr
->size
] != MAGICBYTE
)
1702 static void freehook
__P ((__ptr_t
));
1707 struct hdr
*hdr
= ((struct hdr
*) ptr
) - 1;
1710 __free_hook
= old_free_hook
;
1712 __free_hook
= freehook
;
1715 static __ptr_t mallochook
__P ((size_t));
1722 __malloc_hook
= old_malloc_hook
;
1723 hdr
= (struct hdr
*) malloc (sizeof (struct hdr
) + size
+ 1);
1724 __malloc_hook
= mallochook
;
1729 hdr
->magic
= MAGICWORD
;
1730 ((char *) &hdr
[1])[size
] = MAGICBYTE
;
1731 return (__ptr_t
) (hdr
+ 1);
1734 static __ptr_t reallochook
__P ((__ptr_t
, size_t));
1736 reallochook (ptr
, size
)
1740 struct hdr
*hdr
= ((struct hdr
*) ptr
) - 1;
1743 __free_hook
= old_free_hook
;
1744 __malloc_hook
= old_malloc_hook
;
1745 __realloc_hook
= old_realloc_hook
;
1746 hdr
= (struct hdr
*) realloc ((__ptr_t
) hdr
, sizeof (struct hdr
) + size
+ 1);
1747 __free_hook
= freehook
;
1748 __malloc_hook
= mallochook
;
1749 __realloc_hook
= reallochook
;
1754 ((char *) &hdr
[1])[size
] = MAGICBYTE
;
1755 return (__ptr_t
) (hdr
+ 1);
1760 void (*func
) __P ((void));
1762 extern void abort
__P ((void));
1763 static int mcheck_used
= 0;
1765 abortfunc
= (func
!= NULL
) ? func
: abort
;
1767 /* These hooks may not be safely inserted if malloc is already in use. */
1768 if (!__malloc_initialized
&& !mcheck_used
)
1770 old_free_hook
= __free_hook
;
1771 __free_hook
= freehook
;
1772 old_malloc_hook
= __malloc_hook
;
1773 __malloc_hook
= mallochook
;
1774 old_realloc_hook
= __realloc_hook
;
1775 __realloc_hook
= reallochook
;
1779 return mcheck_used
? 0 : -1;
1781 /* More debugging hooks for `malloc'.
1782 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
1783 Written April 2, 1991 by John Gilmore of Cygnus Support.
1784 Based on mcheck.c by Mike Haertel.
1786 This library is free software; you can redistribute it and/or
1787 modify it under the terms of the GNU Library General Public License as
1788 published by the Free Software Foundation; either version 2 of the
1789 License, or (at your option) any later version.
1791 This library is distributed in the hope that it will be useful,
1792 but WITHOUT ANY WARRANTY; without even the implied warranty of
1793 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1794 Library General Public License for more details.
1796 You should have received a copy of the GNU Library General Public
1797 License along with this library; see the file COPYING.LIB. If
1798 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1799 Cambridge, MA 02139, USA.
1801 The author may be reached (Email) at the address mike@ai.mit.edu,
1802 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1804 #ifndef _MALLOC_INTERNAL
1805 #define _MALLOC_INTERNAL
1811 #ifndef __GNU_LIBRARY__
1812 extern char *getenv ();
1817 static FILE *mallstream
;
1818 static char mallenv
[]= "MALLOC_TRACE";
1819 static char mallbuf
[BUFSIZ
]; /* Buffer for the output. */
1821 /* Address to breakpoint on accesses to... */
1824 /* Old hook values. */
1825 static __ptr_t (*tr_old_morecore
) __P ((ptrdiff_t increment
));
1826 static __ptr_t (*tr_old_lesscore
) __P ((__ptr_t ptr
, ptrdiff_t increment
));
1827 static void (*tr_old_free_hook
) __P ((__ptr_t ptr
));
1828 static __ptr_t (*tr_old_malloc_hook
) __P ((size_t size
));
1829 static __ptr_t (*tr_old_realloc_hook
) __P ((__ptr_t ptr
, size_t size
));
1831 /* This function is called when the block being alloc'd, realloc'd, or
1832 freed has an address matching the variable "mallwatch". In a debugger,
1833 set "mallwatch" to the address of interest, then put a breakpoint on
1836 void tr_break
__P ((void));
1842 static void tr_freehook
__P ((__ptr_t
));
1847 fprintf (mallstream
, "- %p\n", ptr
); /* Be sure to print it first. */
1848 if (ptr
== mallwatch
)
1850 __free_hook
= tr_old_free_hook
;
1852 __free_hook
= tr_freehook
;
1855 static __ptr_t tr_morecore
__P ((ptrdiff_t));
1857 tr_morecore (increment
)
1858 ptrdiff_t increment
;
1862 __morecore
= tr_old_morecore
;
1863 p
= (__ptr_t
) (*__morecore
) (increment
);
1864 __morecore
= tr_morecore
;
1866 fprintf (mallstream
, "$ %p %d\n", p
, increment
);
1871 static __ptr_t tr_lesscore
__P ((__ptr_t
, ptrdiff_t));
1873 tr_lesscore (ptr
, increment
)
1875 ptrdiff_t increment
;
1879 __lesscore
= tr_old_lesscore
;
1880 p
= (__ptr_t
) (*__lesscore
) (ptr
, increment
);
1881 __lesscore
= tr_lesscore
;
1883 fprintf (mallstream
, "* %p (%p, %d)\n", p
, ptr
, increment
);
1888 static __ptr_t tr_mallochook
__P ((size_t));
1890 tr_mallochook (size
)
1895 __malloc_hook
= tr_old_malloc_hook
;
1896 hdr
= (__ptr_t
) malloc (size
);
1897 __malloc_hook
= tr_mallochook
;
1899 /* We could be printing a NULL here; that's OK. */
1900 fprintf (mallstream
, "+ %p %x\n", hdr
, size
);
1902 if (hdr
== mallwatch
)
1908 static __ptr_t tr_reallochook
__P ((__ptr_t
, size_t));
1910 tr_reallochook (ptr
, size
)
1916 if (ptr
== mallwatch
)
1919 __free_hook
= tr_old_free_hook
;
1920 __malloc_hook
= tr_old_malloc_hook
;
1921 __realloc_hook
= tr_old_realloc_hook
;
1922 hdr
= (__ptr_t
) realloc (ptr
, size
);
1923 __free_hook
= tr_freehook
;
1924 __malloc_hook
= tr_mallochook
;
1925 __realloc_hook
= tr_reallochook
;
1927 /* Failed realloc. */
1928 fprintf (mallstream
, "! %p %x\n", ptr
, size
);
1930 fprintf (mallstream
, "< %p\n> %p %x\n", ptr
, hdr
, size
);
1932 if (hdr
== mallwatch
)
1938 /* We enable tracing if either the environment variable MALLOC_TRACE
1939 is set, or if the variable mallwatch has been patched to an address
1940 that the debugging user wants us to stop on. When patching mallwatch,
1941 don't forget to set a breakpoint on tr_break! */
1948 mallfile
= getenv (mallenv
);
1949 if (mallfile
!= NULL
|| mallwatch
!= NULL
)
1951 mallstream
= fopen (mallfile
!= NULL
? mallfile
: "/dev/null", "w");
1952 if (mallstream
!= NULL
)
1954 /* Be sure it doesn't malloc its buffer! */
1955 setbuf (mallstream
, mallbuf
);
1956 fprintf (mallstream
, "= Start\n");
1957 #if defined(emacs) && defined(VMS)
1958 fprintf (mallstream
, "= Initial buffer spans %p -- %p\n",
1959 vms_initial_buffer
, vms_end_brk
+ 1);
1961 tr_old_morecore
= __morecore
;
1962 __morecore
= tr_morecore
;
1963 tr_old_lesscore
= __lesscore
;
1964 __lesscore
= tr_lesscore
;
1965 tr_old_free_hook
= __free_hook
;
1966 __free_hook
= tr_freehook
;
1967 tr_old_malloc_hook
= __malloc_hook
;
1968 __malloc_hook
= tr_mallochook
;
1969 tr_old_realloc_hook
= __realloc_hook
;
1970 __realloc_hook
= tr_reallochook
;
1974 /* Access the statistics maintained by `malloc'.
1975 Copyright 1990, 1991, 1992 Free Software Foundation
1976 Written May 1989 by Mike Haertel.
1978 This library is free software; you can redistribute it and/or
1979 modify it under the terms of the GNU Library General Public License as
1980 published by the Free Software Foundation; either version 2 of the
1981 License, or (at your option) any later version.
1983 This library is distributed in the hope that it will be useful,
1984 but WITHOUT ANY WARRANTY; without even the implied warranty of
1985 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1986 Library General Public License for more details.
1988 You should have received a copy of the GNU Library General Public
1989 License along with this library; see the file COPYING.LIB. If
1990 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1991 Cambridge, MA 02139, USA.
1993 The author may be reached (Email) at the address mike@ai.mit.edu,
1994 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1996 #ifndef _MALLOC_INTERNAL
1997 #define _MALLOC_INTERNAL
2004 struct mstats result
;
2006 result
.bytes_total
= (char *) (*__morecore
) (0) - _heapbase
;
2007 result
.chunks_used
= _chunks_used
;
2008 result
.bytes_used
= _bytes_used
;
2009 result
.chunks_free
= _chunks_free
;
2010 result
.bytes_free
= _bytes_free
;