diff options
Diffstat (limited to 'src/vmsgmalloc.c')
| -rw-r--r-- | src/vmsgmalloc.c | 2012 |
1 files changed, 0 insertions, 2012 deletions
diff --git a/src/vmsgmalloc.c b/src/vmsgmalloc.c deleted file mode 100644 index 93a3fd7f8bd..00000000000 --- a/src/vmsgmalloc.c +++ /dev/null @@ -1,2012 +0,0 @@ -/* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */ - -#define _MALLOC_INTERNAL - -/* The malloc headers and source files from the C library follow here. */ - -/* Declarations for `malloc' and friends. - Copyright 1990, 1991, 1992, 1993, 1999 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This file is part of GNU Emacs. - -GNU Emacs is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Emacs is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_H - -#define _MALLOC_H 1 - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) -#undef __P -#define __P(args) args -#undef __const -#define __const const -#undef __ptr_t -#define __ptr_t void * -#else /* Not C++ or ANSI C. */ -#undef __P -#define __P(args) () -#undef __const -#define __const -#undef __ptr_t -#define __ptr_t char * -#endif /* C++ or ANSI C. */ - -#ifndef NULL -#define NULL 0 -#endif - -#if defined (HAVE_CONFIG_H) || defined (emacs) -#include <config.h> -#endif - -#ifdef __STDC__ -#include <stddef.h> -#else -#ifdef VMS /* The following are defined in stdio.h, but we need it NOW! - But do NOT do it with defines here, for then, VAX C is going - to barf when it gets to stdio.h and the typedefs in there! */ -typedef unsigned int size_t; -typedef int ptrdiff_t; -#else /* not VMS */ -#undef size_t -#define size_t unsigned int -#undef ptrdiff_t -#define ptrdiff_t int -#endif /* VMS */ -#endif - - -/* Allocate SIZE bytes of memory. */ -extern __ptr_t malloc __P ((size_t __size)); -/* Re-allocate the previously allocated block - in __ptr_t, making the new block SIZE bytes long. */ -extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size)); -/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ -extern __ptr_t calloc __P ((size_t __nmemb, size_t __size)); -/* Free a block allocated by `malloc', `realloc' or `calloc'. */ -extern void free __P ((__ptr_t __ptr)); - -/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ -extern __ptr_t memalign __P ((size_t __alignment, size_t __size)); - -/* Allocate SIZE bytes on a page boundary. */ -extern __ptr_t valloc __P ((size_t __size)); - -#ifdef VMS -/* VMS hooks to deal with two heaps */ -/* Allocate SIZE bytes of memory. */ -extern __ptr_t __vms_malloc __P ((size_t __size)); -/* Re-allocate the previously allocated block - in __ptr_t, making the new block SIZE bytes long. */ -extern __ptr_t __vms_realloc __P ((__ptr_t __ptr, size_t __size)); -/* Free a block allocated by `malloc', `realloc' or `calloc'. */ -extern void __vms_free __P ((__ptr_t __ptr)); -#endif - -#ifdef _MALLOC_INTERNAL - -#include <stdio.h> /* Harmless, gets __GNU_LIBRARY__ defined. */ - -#if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) || defined(USG) -#include <string.h> -#else -#ifndef memset -#define memset(s, zero, n) bzero ((s), (n)) -#endif -#ifndef memcpy -#define memcpy(d, s, n) bcopy ((s), (d), (n)) -#endif -#ifndef memmove -#define memmove(d, s, n) bcopy ((s), (d), (n)) -#endif -#endif - - -#if defined(__GNU_LIBRARY__) || defined(__STDC__) -#include <limits.h> -#else -#define CHAR_BIT 8 -#endif - -/* The allocator divides the heap into blocks of fixed size; large - requests receive one or more whole blocks, and small requests - receive a fragment of a block. Fragment sizes are powers of two, - and all fragments of a block are the same size. When all the - fragments in a block have been freed, the block itself is freed. */ -#define INT_BIT (CHAR_BIT * sizeof(int)) -#ifdef VMS -#define BLOCKLOG 9 -#else -#define BLOCKLOG (INT_BIT > 16 ? 12 : 9) -#endif -#define BLOCKSIZE (1 << BLOCKLOG) -#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) - -/* Determine the amount of memory spanned by the initial heap table - (not an absolute limit). */ -#define HEAP (INT_BIT > 16 ? 4194304 : 65536) - -/* Number of contiguous free blocks allowed to build up at the end of - memory before they will be returned to the system. */ -#define FINAL_FREE_BLOCKS 8 - -/* Data structure giving per-block information. */ -typedef union - { - /* Heap information for a busy block. */ - struct - { - /* Zero for a large block, or positive giving the - logarithm to the base two of the fragment size. */ - int type; - union - { - struct - { - size_t nfree; /* Free fragments in a fragmented block. */ - size_t first; /* First free fragment of the block. */ - } frag; - /* Size (in blocks) of a large cluster. */ - size_t size; - } info; - } busy; - /* Heap information for a free block - (that may be the first of a free cluster). */ - struct - { - size_t size; /* Size (in blocks) of a free cluster. */ - size_t next; /* Index of next free cluster. */ - size_t prev; /* Index of previous free cluster. */ - } free; - } malloc_info; - -/* Pointer to first block of the heap. */ -extern char *_heapbase; - -/* Table indexed by block number giving per-block information. */ -extern malloc_info *_heapinfo; - -/* Address to block number and vice versa. */ -#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) -#define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) - -/* Current search index for the heap table. */ -extern size_t _heapindex; - -/* Limit of valid info table indices. */ -extern size_t _heaplimit; - -/* Doubly linked lists of free fragments. */ -struct list - { - struct list *next; - struct list *prev; - }; - -/* Free list headers for each fragment size. */ -extern struct list _fraghead[]; - -/* List of blocks allocated with `memalign' (or `valloc'). */ -struct alignlist - { - struct alignlist *next; - __ptr_t aligned; /* The address that memaligned returned. */ - __ptr_t exact; /* The address that malloc returned. */ - }; -extern struct alignlist *_aligned_blocks; - -/* Instrumentation. */ -extern size_t _chunks_used; -extern size_t _bytes_used; -extern size_t _chunks_free; -extern size_t _bytes_free; - -/* Internal version of `free' used in `morecore' (malloc.c). */ -extern void _free_internal __P ((__ptr_t __ptr)); - -#endif /* _MALLOC_INTERNAL. */ - -/* Underlying allocation function; successive calls should - return contiguous pieces of memory. */ -/* It does NOT always return contiguous pieces of memory on VMS. */ -extern __ptr_t (*__morecore) __P ((ptrdiff_t __size)); - -/* Underlying deallocation function. It accepts both a pointer and - a size to back up. It is implementation dependent what is really - used. */ -extern __ptr_t (*__lesscore) __P ((__ptr_t __ptr, ptrdiff_t __size)); - -/* Default value of `__morecore'. */ -extern __ptr_t __default_morecore __P ((ptrdiff_t __size)); - -/* Default value of `__lesscore'. */ -extern __ptr_t __default_lesscore __P ((__ptr_t __ptr, ptrdiff_t __size)); - -#ifdef VMS -/* Default value of `__morecore'. */ -extern __ptr_t __vms_morecore __P ((ptrdiff_t __size)); - -/* Default value of `__lesscore'. */ -extern __ptr_t __vms_lesscore __P ((__ptr_t __ptr, ptrdiff_t __size)); -#endif - -/* If not NULL, this function is called after each time - `__morecore' is called to increase the data size. */ -extern void (*__after_morecore_hook) __P ((void)); - -/* If not NULL, this function is called after each time - `__lesscore' is called to increase the data size. */ -extern void (*__after_lesscore_hook) __P ((void)); - -/* Nonzero if `malloc' has been called and done its initialization. */ -extern int __malloc_initialized; - -/* Hooks for debugging versions. */ -extern void (*__free_hook) __P ((__ptr_t __ptr)); -extern __ptr_t (*__malloc_hook) __P ((size_t __size)); -extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size)); - -/* Activate a standard collection of debugging hooks. */ -extern int mcheck __P ((void (*__func) __P ((void)))); - -/* Activate a standard collection of tracing hooks. */ -extern void mtrace __P ((void)); - -/* Statistics available to the user. */ -struct mstats - { - size_t bytes_total; /* Total size of the heap. */ - size_t chunks_used; /* Chunks allocated by the user. */ - size_t bytes_used; /* Byte total of user-allocated chunks. */ - size_t chunks_free; /* Chunks in the free list. */ - size_t bytes_free; /* Byte total of chunks in the free list. */ - }; - -/* Pick up the current statistics. */ -extern struct mstats mstats __P ((void)); - -/* Call WARNFUN with a warning message when memory usage is high. */ -extern void memory_warnings __P ((__ptr_t __start, - void (*__warnfun) __P ((__const char *)))); - - -/* Relocating allocator. */ - -/* Allocate SIZE bytes, and store the address in *HANDLEPTR. */ -extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, size_t __size)); - -/* Free the storage allocated in HANDLEPTR. */ -extern void r_alloc_free __P ((__ptr_t *__handleptr)); - -/* Adjust the block at HANDLEPTR to be SIZE bytes long. */ -extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, size_t __size)); - - -#ifdef __cplusplus -} -#endif - -#endif /* malloc.h */ -/* Memory allocator `malloc'. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#ifdef VMS -/* How to really get more memory. */ -__ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __vms_morecore; -#else -/* How to really get more memory. */ -__ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore; -#endif - -/* Debugging hook for `malloc'. */ -#ifdef VMS -__ptr_t (*__malloc_hook) __P ((size_t __size)) = __vms_malloc; -#else -__ptr_t (*__malloc_hook) __P ((size_t __size)); -#endif - -/* Pointer to the base of the first block. */ -char *_heapbase; - -/* Block information table. Allocated with align/__free (not malloc/free). */ -malloc_info *_heapinfo; - -/* Number of info entries. */ -static size_t heapsize; - -/* Search index in the info table. */ -size_t _heapindex; - -/* Limit of valid info table indices. */ -size_t _heaplimit; - -/* Free lists for each fragment size. */ -struct list _fraghead[BLOCKLOG]; - -/* Instrumentation. */ -size_t _chunks_used; -size_t _bytes_used; -size_t _chunks_free; -size_t _bytes_free; - -/* Are you experienced? */ -int __malloc_initialized; - -void (*__after_morecore_hook) __P ((void)); - -/* Aligned allocation. */ -static __ptr_t align __P ((size_t)); -static __ptr_t -align (size) - size_t size; -{ - __ptr_t result; - unsigned long int adj; - - result = (*__morecore) (size); - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % BLOCKSIZE; - if (adj != 0) - { - adj = BLOCKSIZE - adj; - (void) (*__morecore) (adj); - result = (char *) result + adj; - } - - if (__after_morecore_hook) - (*__after_morecore_hook) (); - - return result; -} - -/* Set everything up and remember that we have. */ -static int initialize __P ((void)); -static int -initialize () -{ -#ifdef RL_DEBUG - extern VMS_present_buffer(); - printf("__malloc_initialized = %d\n", __malloc_initialized); - VMS_present_buffer(); -#endif - heapsize = HEAP / BLOCKSIZE; - _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info)); - if (_heapinfo == NULL) - return 0; - memset (_heapinfo, 0, heapsize * sizeof (malloc_info)); - _heapinfo[0].free.size = 0; - _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; - _heapindex = 0; - _heapbase = (char *) _heapinfo; -#ifdef RL_DEBUG -/* debug */ - printf("_heapbase = 0%o/0x%x/%d\n", _heapbase, _heapbase, _heapbase); -/* end debug */ -#endif - __malloc_initialized = 1; - return 1; -} - -/* Get neatly aligned memory, initializing or - growing the heap info table as necessary. */ -static __ptr_t morecore __P ((size_t)); -static __ptr_t -morecore (size) - size_t size; -{ - __ptr_t result; - malloc_info *newinfo, *oldinfo; - size_t newsize; - - result = align (size); - if (result == NULL) - return NULL; - - /* Check if we need to grow the info table. */ - if ((size_t) BLOCK ((char *) result + size) > heapsize) - { - newsize = heapsize; - while ((size_t) BLOCK ((char *) result + size) > newsize) - newsize *= 2; - newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); - if (newinfo == NULL) - { - (*__lesscore) (result, size); - return NULL; - } - memset (newinfo, 0, newsize * sizeof (malloc_info)); - memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); - oldinfo = _heapinfo; - newinfo[BLOCK (oldinfo)].busy.type = 0; - newinfo[BLOCK (oldinfo)].busy.info.size - = BLOCKIFY (heapsize * sizeof (malloc_info)); - _heapinfo = newinfo; - _free_internal (oldinfo); - heapsize = newsize; - } - - _heaplimit = BLOCK ((char *) result + size); - return result; -} - -/* Allocate memory from the heap. */ -__ptr_t -malloc (size) - size_t size; -{ - __ptr_t result; - size_t block, blocks, lastblocks, start; - register size_t i; - struct list *next; - - if (size == 0) - return NULL; - - if (__malloc_hook != NULL) - return (*__malloc_hook) (size); - - if (!__malloc_initialized) - if (!initialize ()) - return NULL; - - if (size < sizeof (struct list)) - size = sizeof (struct list); - - /* Determine the allocation policy based on the request size. */ - if (size <= BLOCKSIZE / 2) - { - /* Small allocation to receive a fragment of a block. - Determine the logarithm to base two of the fragment size. */ - register size_t log = 1; - --size; - while ((size /= 2) != 0) - ++log; - - /* Look in the fragment lists for a - free fragment of the desired size. */ - next = _fraghead[log].next; - if (next != NULL) - { - /* There are free fragments of this size. - Pop a fragment out of the fragment list and return it. - Update the block's nfree and first counters. */ - result = (__ptr_t) next; - next->prev->next = next->next; - if (next->next != NULL) - next->next->prev = next->prev; - block = BLOCK (result); - if (--_heapinfo[block].busy.info.frag.nfree != 0) - _heapinfo[block].busy.info.frag.first = (unsigned long int) - ((unsigned long int) ((char *) next->next - (char *) NULL) - % BLOCKSIZE) >> log; - - /* Update the statistics. */ - ++_chunks_used; - _bytes_used += 1 << log; - --_chunks_free; - _bytes_free -= 1 << log; - } - else - { - /* No free fragments of the desired size, so get a new block - and break it into fragments, returning the first. */ - result = malloc (BLOCKSIZE); - if (result == NULL) - return NULL; - - /* Link all fragments but the first into the free list. */ - for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) - { - next = (struct list *) ((char *) result + (i << log)); -#ifdef RL_DEBUG - printf("DEBUG: malloc (%d): next = %p\n", size, next); -#endif - next->next = _fraghead[log].next; - next->prev = &_fraghead[log]; - next->prev->next = next; - if (next->next != NULL) - next->next->prev = next; - } - - /* Initialize the nfree and first counters for this block. */ - block = BLOCK (result); - _heapinfo[block].busy.type = log; - _heapinfo[block].busy.info.frag.nfree = i - 1; - _heapinfo[block].busy.info.frag.first = i - 1; - - _chunks_free += (BLOCKSIZE >> log) - 1; - _bytes_free += BLOCKSIZE - (1 << log); - _bytes_used -= BLOCKSIZE - (1 << log); - } - } - else - { - /* Large allocation to receive one or more blocks. - Search the free list in a circle starting at the last place visited. - If we loop completely around without finding a large enough - space we will have to get more memory from the system. */ - blocks = BLOCKIFY (size); - start = block = _heapindex; - while (_heapinfo[block].free.size < blocks) - { - block = _heapinfo[block].free.next; - if (block == start) - { - /* Need to get more from the system. Check to see if - the new core will be contiguous with the final free - block; if so we don't need to get as much. */ - block = _heapinfo[0].free.prev; - lastblocks = _heapinfo[block].free.size; - if (_heaplimit != 0 && block + lastblocks == _heaplimit && - (*__morecore) (0) == ADDRESS (block + lastblocks) && - (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL) - { - _heapinfo[block].free.size = blocks; - _bytes_free += (blocks - lastblocks) * BLOCKSIZE; - continue; - } - result = morecore (blocks * BLOCKSIZE); - if (result == NULL) - return NULL; - block = BLOCK (result); - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - return result; - } - } - - /* At this point we have found a suitable free list entry. - Figure out how to remove what we need from the list. */ - result = ADDRESS (block); - if (_heapinfo[block].free.size > blocks) - { - /* The block we found has a bit left over, - so relink the tail end back into the free list. */ - _heapinfo[block + blocks].free.size - = _heapinfo[block].free.size - blocks; - _heapinfo[block + blocks].free.next - = _heapinfo[block].free.next; - _heapinfo[block + blocks].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[_heapinfo[block].free.next].free.prev - = _heapindex = block + blocks; - } - else - { - /* The block exactly matches our requirements, - so just remove it from the list. */ - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapindex = _heapinfo[block].free.next; - --_chunks_free; - } - - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - _bytes_free -= blocks * BLOCKSIZE; - } - - return result; -} -/* Free a block of memory allocated by `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#ifdef VMS -/* How to really get more memory. */ -__ptr_t (*__lesscore) __P ((__ptr_t __ptr,ptrdiff_t __size)) = __vms_lesscore; -#else -/* How to really get more memory. */ -__ptr_t (*__lesscore) __P ((__ptr_t __ptr,ptrdiff_t __size)) = __default_lesscore; -#endif - -/* Debugging hook for free. */ -#ifdef VMS -void (*__free_hook) __P ((__ptr_t __ptr)) = __vms_free; -#else -void (*__free_hook) __P ((__ptr_t __ptr)); -#endif - -/* List of blocks allocated by memalign. */ -struct alignlist *_aligned_blocks = NULL; - -/* Return memory to the heap. - Like `free' but don't call a __free_hook if there is one. */ -void -_free_internal (ptr) - __ptr_t ptr; -{ - int type; - size_t block, blocks; - register size_t i; - struct list *prev, *next; - - block = BLOCK (ptr); - - type = _heapinfo[block].busy.type; - switch (type) - { - case 0: - /* Get as many statistics as early as we can. */ - --_chunks_used; - _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE; - _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE; - - /* Find the free cluster previous to this one in the free list. - Start searching at the last block referenced; this may benefit - programs with locality of allocation. */ - i = _heapindex; - if (i > block) - while (i > block) - i = _heapinfo[i].free.prev; - else - { - do - i = _heapinfo[i].free.next; - while (i > 0 && i < block); - i = _heapinfo[i].free.prev; - } - - /* Determine how to link this block into the free list. */ - if (block == i + _heapinfo[i].free.size) - { - /* Coalesce this block with its predecessor. */ - _heapinfo[i].free.size += _heapinfo[block].busy.info.size; - block = i; - } - else - { - /* Really link this block back into the free list. */ - _heapinfo[block].free.size = _heapinfo[block].busy.info.size; - _heapinfo[block].free.next = _heapinfo[i].free.next; - _heapinfo[block].free.prev = i; - _heapinfo[i].free.next = block; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - ++_chunks_free; - } - - /* Now that the block is linked in, see if we can coalesce it - with its successor (by deleting its successor from the list - and adding in its size). */ - if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) - { - _heapinfo[block].free.size - += _heapinfo[_heapinfo[block].free.next].free.size; - _heapinfo[block].free.next - = _heapinfo[_heapinfo[block].free.next].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - --_chunks_free; - } - - /* Now see if we can return stuff to the system. */ - blocks = _heapinfo[block].free.size; - if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit - && (*__morecore) (0) == ADDRESS (block + blocks)) - { - register size_t bytes = blocks * BLOCKSIZE; - _heaplimit -= blocks; - (*__lesscore) (ADDRESS(block), bytes); - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[block].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - block = _heapinfo[block].free.prev; - --_chunks_free; - _bytes_free -= bytes; - } - - /* Set the next search to begin at this block. */ - _heapindex = block; - break; - - default: - /* Do some of the statistics. */ - --_chunks_used; - _bytes_used -= 1 << type; - ++_chunks_free; - _bytes_free += 1 << type; - - /* Get the address of the first free fragment in this block. */ - prev = (struct list *) ((char *) ADDRESS (block) + - (_heapinfo[block].busy.info.frag.first << type)); -#ifdef RL_DEBUG - printf("_free_internal(0%o/0x%x/%d) :\n", ptr, ptr, ptr); - printf(" block = %d, type = %d, prev = 0%o/0x%x/%d\n", - block, type, prev, prev, prev); - printf(" _heapinfo[block=%d].busy.info.frag.nfree = %d\n", - block, - _heapinfo[block].busy.info.frag.nfree); -#endif - - if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1) - { - /* If all fragments of this block are free, remove them - from the fragment list and free the whole block. */ - next = prev; - for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i) - next = next->next; - prev->prev->next = next; - if (next != NULL) - next->prev = prev->prev; - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = 1; - - /* Keep the statistics accurate. */ - ++_chunks_used; - _bytes_used += BLOCKSIZE; - _chunks_free -= BLOCKSIZE >> type; - _bytes_free -= BLOCKSIZE; - - free (ADDRESS (block)); - } - else if (_heapinfo[block].busy.info.frag.nfree != 0) - { - /* If some fragments of this block are free, link this - fragment into the fragment list after the first free - fragment of this block. */ -#ifdef RL_DEBUG - printf("There's a bug hiding here (%s:%d), so I will print some values\n", __FILE__, __LINE__); -#endif - next = (struct list *) ptr; -#ifdef RL_DEBUG - printf(" (struct list *)next (0%o / 0x%x / %d) ->\n", next, next, next); - printf(" next = 0%o / 0x%x / %d\n", next->next,next->next,next->next); - printf(" prev = 0%o / 0x%x / %d\n", next->prev,next->prev,next->prev); - printf(" (struct list *)prev (0%o / 0x%x / %d)->\n", prev, prev, prev); - printf(" next = 0%o / 0x%x / %d\n", prev->next,prev->next,prev->next); - printf(" prev = 0%o / 0x%x / %d\n", prev->prev,prev->prev,prev->prev); -#endif - next->next = prev->next; - next->prev = prev; - prev->next = next; - if (next->next != NULL) - next->next->prev = next; - ++_heapinfo[block].busy.info.frag.nfree; - } - else - { - /* No fragments of this block are free, so link this - fragment into the fragment list and announce that - it is the first free fragment of this block. */ - prev = (struct list *) ptr; - _heapinfo[block].busy.info.frag.nfree = 1; - _heapinfo[block].busy.info.frag.first = (unsigned long int) - ((unsigned long int) ((char *) ptr - (char *) NULL) - % BLOCKSIZE >> type); - prev->next = _fraghead[type].next; - prev->prev = &_fraghead[type]; - prev->prev->next = prev; - if (prev->next != NULL) - prev->next->prev = prev; - } - break; - } -} - -/* Return memory to the heap. */ -void -free (ptr) - __ptr_t ptr; -{ - register struct alignlist *l; - - if (ptr == NULL) - return; - - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == ptr) - { - l->aligned = NULL; /* Mark the slot in the list as free. */ - ptr = l->exact; - break; - } - - if (__free_hook != NULL) - (*__free_hook) (ptr); - else - _free_internal (ptr); -} -/* Change the size of a block allocated by `malloc'. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#define min(A, B) ((A) < (B) ? (A) : (B)) - -/* Debugging hook for realloc. */ -#ifdef VMS -__ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size)) = __vms_realloc; -#else -__ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size)); -#endif - -/* Resize the given region to the new size, returning a pointer - to the (possibly moved) region. This is optimized for speed; - some benchmarks seem to indicate that greater compactness is - achieved by unconditionally allocating and copying to a - new region. This module has incestuous knowledge of the - internals of both free and malloc. */ -__ptr_t -realloc (ptr, size) - __ptr_t ptr; - size_t size; -{ - __ptr_t result; - int type; - size_t block, blocks, oldlimit; - - if (size == 0) - { - free (ptr); - return malloc (0); - } - else if (ptr == NULL) - return malloc (size); - - if (__realloc_hook != NULL) - return (*__realloc_hook) (ptr, size); - - block = BLOCK (ptr); - - type = _heapinfo[block].busy.type; - switch (type) - { - case 0: - /* Maybe reallocate a large block to a small fragment. */ - if (size <= BLOCKSIZE / 2) - { - result = malloc (size); - if (result != NULL) - { - memcpy (result, ptr, size); - free (ptr); - return result; - } - } - - /* The new size is a large allocation as well; - see if we can hold it in place. */ - blocks = BLOCKIFY (size); - if (blocks < _heapinfo[block].busy.info.size) - { - /* The new size is smaller; return - excess memory to the free list. */ - _heapinfo[block + blocks].busy.type = 0; - _heapinfo[block + blocks].busy.info.size - = _heapinfo[block].busy.info.size - blocks; - _heapinfo[block].busy.info.size = blocks; - free (ADDRESS (block + blocks)); - result = ptr; - } - else if (blocks == _heapinfo[block].busy.info.size) - /* No size change necessary. */ - result = ptr; - else - { - /* Won't fit, so allocate a new region that will. - Free the old region first in case there is sufficient - adjacent free space to grow without moving. */ - blocks = _heapinfo[block].busy.info.size; - /* Prevent free from actually returning memory to the system. */ - oldlimit = _heaplimit; - _heaplimit = 0; - free (ptr); - _heaplimit = oldlimit; - result = malloc (size); - if (result == NULL) - { - /* Now we're really in trouble. We have to unfree - the thing we just freed. Unfortunately it might - have been coalesced with its neighbors. */ - if (_heapindex == block) - (void) malloc (blocks * BLOCKSIZE); - else - { - __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE); - (void) malloc (blocks * BLOCKSIZE); - free (previous); - } - return NULL; - } - if (ptr != result) - memmove (result, ptr, blocks * BLOCKSIZE); - } - break; - - default: - /* Old size is a fragment; type is logarithm - to base two of the fragment size. */ - if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) - /* The new size is the same kind of fragment. */ - result = ptr; - else - { - /* The new size is different; allocate a new space, - and copy the lesser of the new size and the old. */ - result = malloc (size); - if (result == NULL) - return NULL; - memcpy (result, ptr, min (size, (size_t) 1 << type)); - free (ptr); - } - break; - } - - return result; -} -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Allocate an array of NMEMB elements each SIZE bytes long. - The entire array is initialized to zeros. */ -__ptr_t -calloc (nmemb, size) - register size_t nmemb; - register size_t size; -{ - register __ptr_t result = malloc (nmemb * size); - - if (result != NULL) - (void) memset (result, 0, nmemb * size); - - return result; -} -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU C Library; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#ifndef __GNU_LIBRARY__ -#define __sbrk sbrk -#ifdef VMS -#define __brk brk -#endif -#endif - -extern __ptr_t __sbrk __P ((int increment)); - -#ifndef NULL -#define NULL 0 -#endif - -#if defined(emacs) && defined(VMS) -/* Dumping of Emacs on VMS does not include the heap! - So let's make a huge array from which initial data will be - allocated. - - VMS_ALLOCATION_SIZE is the amount of memory we preallocate. - We don't want it to be too large, because it only gives a larger - dump file. The way to check how much is really used is to - make VMS_ALLOCATION_SIZE very large, to link Emacs with the - debugger, run Emacs, check how much was allocated. Then set - VMS_ALLOCATION_SIZE to something suitable, recompile gmalloc, - relink Emacs, and you should be off. - - N.B. This is experimental, but it worked quite fine on Emacs 18. -*/ -#ifndef VMS_ALLOCATION_SIZE -#define VMS_ALLOCATION_SIZE (512*(512+128)) -#endif - -int vms_out_initial = 0; -char vms_initial_buffer[VMS_ALLOCATION_SIZE]; -char *vms_current_brk = vms_initial_buffer; -char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1]; - -__ptr_t -__vms_initial_morecore (increment) - ptrdiff_t increment; -{ - __ptr_t result = NULL; - __ptr_t temp; - - /* It's far easier to make the alignment here than to make a - kludge in align () */ -#ifdef RL_DEBUG - printf(">>>foo... %p...", vms_current_brk); -#endif - vms_current_brk += (BLOCKSIZE - ((unsigned long) vms_current_brk - & (BLOCKSIZE - 1))) & (BLOCKSIZE - 1); -#ifdef RL_DEBUG - printf("bar... %p. (%d)\n", vms_current_brk, increment); -#endif - temp = vms_current_brk + (int) increment; - if (temp <= vms_end_brk) - { - if (increment >= 0) - result = vms_current_brk; - else - result = temp; - vms_current_brk = temp; - } - return result; -} - -__ptr_t -__vms_initial_lesscore (ptr, size) - __ptr_t ptr; - ptrdiff_t size; -{ - if (ptr >= vms_initial_buffer - && ptr < vms_initial_buffer+VMS_ALLOCATION_SIZE) - { - vms_current_brk = ptr; - return vms_current_brk; - } - return vms_current_brk; -} - -VMS_present_buffer() -{ - printf("Vms initial buffer starts at 0%o/0x%x/%d and ends at 0%o/0x%x/%d\n", - vms_initial_buffer, vms_initial_buffer, vms_initial_buffer, - vms_end_brk, vms_end_brk, vms_end_brk); -} -#endif /* defined(emacs) && defined(VMS) */ - -#ifdef VMS -/* Unfortunately, the VAX C sbrk() is buggy. For example, it returns - memory in 512 byte chunks (not a bug, but there's more), AND it - adds an extra 512 byte chunk if you ask for a multiple of 512 - bytes (you ask for 512 bytes, you get 1024 bytes...). And also, - the VAX C sbrk does not handle negative increments... - There's a similar problem with brk(). Even if you set the break - to an even page boundary, it gives you one extra page... */ - -static char vms_brk_info_fetched = -1; /* -1 if this is the first time, otherwise - bit 0 set if 'increment' needs adjustment - bit 1 set if the value to brk() needs adjustment */ -static char *vms_brk_start = 0; -static char *vms_brk_end = 0; -static char *vms_brk_current = 0; -#endif - -/* Allocate INCREMENT more bytes of data space, - and return the start of data space, or NULL on errors. - If INCREMENT is negative, shrink data space. */ -__ptr_t -__default_morecore (increment) - ptrdiff_t increment; -{ - __ptr_t result; -#ifdef VMS - __ptr_t temp; - -#ifdef RL_DEBUG - printf("DEBUG: morecore: increment = %x\n", increment); - printf(" @ start: vms_brk_info_fetched = %x\n", vms_brk_info_fetched); - printf(" vms_brk_start = %p\n", vms_brk_start); - printf(" vms_brk_current = %p\n", vms_brk_current); - printf(" vms_brk_end = %p\n", vms_brk_end); - printf(" @ end: "); -#endif - - if (vms_brk_info_fetched < 0) - { - vms_brk_current = vms_brk_start = __sbrk (512); - vms_brk_end = __sbrk (0); - if (vms_brk_end - vms_brk_current == 1024) - vms_brk_info_fetched = 1; - else - vms_brk_info_fetched = 0; - vms_brk_end = brk(vms_brk_start); - if (vms_brk_end != vms_brk_start) - vms_brk_info_fetched |= 2; -#ifdef RL_DEBUG - printf("vms_brk_info_fetched = %x\n", vms_brk_info_fetched); - printf(" vms_brk_start = %p\n", vms_brk_start); - printf(" vms_brk_current = %p\n", vms_brk_current); - printf(" vms_brk_end = %p\n", vms_brk_end); - printf(" "); -#endif - } - - if (increment < 0) - { - printf("BZZZZZT! ERROR: __default_morecore does NOT take negative args\n"); - return NULL; - } - - if (increment > 0) - { - result = vms_brk_current; - temp = vms_brk_current + increment; - - if (temp > vms_brk_end) - { - __ptr_t foo; - - foo = __sbrk (0); - if (foo == vms_brk_end) - { - increment = temp - vms_brk_end; - if (increment > (vms_brk_info_fetched & 1)) - increment -= (vms_brk_info_fetched & 1); - foo = __sbrk(increment); -#ifdef RL_DEBUG - printf("__sbrk(%d) --> %p\n", increment, foo); -#endif - if (foo == (__ptr_t) -1) - return NULL; -#ifdef RL_DEBUG - printf(" "); -#endif - } - else - { - result = __sbrk (increment); - - if (result == (__ptr_t) -1) - return NULL; - - temp = result + increment; - } - - vms_brk_end = __sbrk(0); - } - vms_brk_current = temp; -#ifdef RL_DEBUG - printf("vms_brk_current = %p\n", vms_brk_current); - printf(" vms_brk_end = %p\n", vms_brk_end); -#endif - return result; - } -#ifdef RL_DEBUG - printf(" nothing more...\n"); -#endif - - /* OK, so the user wanted to check where the heap limit is. Let's - see if the system thinks it is where we think it is. */ - temp = __sbrk (0); - if (temp != vms_brk_end) - { - /* the value has changed. - Let's trust the system and modify our value */ - vms_brk_current = vms_brk_end = temp; - } - return vms_brk_current; - -#else /* not VMS */ - result = __sbrk ((int) increment); - if (result == (__ptr_t) -1) - return NULL; - return result; -#endif /* VMS */ -} - -__ptr_t -__default_lesscore (ptr, size) - __ptr_t ptr; - ptrdiff_t size; -{ -#ifdef VMS - if (vms_brk_end != 0) - { - vms_brk_current = ptr; - if (vms_brk_current < vms_brk_start) - vms_brk_current = vms_brk_start; - vms_brk_end = (char *) vms_brk_current - - ((vms_brk_info_fetched >> 1) & 1); -#ifdef RL_DEBUG - printf("<<<bar... %p (%p (%p, %d))...", - vms_brk_end, vms_brk_current, ptr, size); -#endif - vms_brk_end = __brk (vms_brk_end); -#ifdef RL_DEBUG - printf("foo... %p.\n", vms_brk_end); -#endif - } - - return vms_brk_current; -#else /* not VMS */ - __default_morecore (-size); -#endif -} - -/* Allocate memory on a page boundary. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#if defined (emacs) || defined (HAVE_CONFIG_H) -#include "config.h" -#endif - -#ifdef __GNU_LIBRARY__ -extern size_t __getpagesize __P ((void)); -#else -#if !defined(USG) && !defined(VMS) -extern size_t getpagesize __P ((void)); -#define __getpagesize() getpagesize() -#else -#include <sys/param.h> -#ifdef EXEC_PAGESIZE -#define __getpagesize() EXEC_PAGESIZE -#else /* No EXEC_PAGESIZE. */ -#ifdef NBPG -#ifndef CLSIZE -#define CLSIZE 1 -#endif /* No CLSIZE. */ -#define __getpagesize() (NBPG * CLSIZE) -#else /* No NBPG. */ -#define __getpagesize() NBPC -#endif /* NBPG. */ -#endif /* EXEC_PAGESIZE. */ -#endif /* USG. */ -#endif - -static size_t pagesize; - -__ptr_t -valloc (size) - size_t size; -{ - if (pagesize == 0) - pagesize = __getpagesize (); - - return memalign (pagesize, size); -} -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -__ptr_t -memalign (alignment, size) - size_t alignment; - size_t size; -{ - __ptr_t result; - unsigned long int adj; - - size = ((size + alignment - 1) / alignment) * alignment; - - result = malloc (size); - if (result == NULL) - return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; - if (adj != 0) - { - struct alignlist *l; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ - break; - if (l == NULL) - { - l = (struct alignlist *) malloc (sizeof (struct alignlist)); - if (l == NULL) - { - free (result); - return NULL; - } - } - l->exact = result; - result = l->aligned = (char *) result + alignment - adj; - l->next = _aligned_blocks; - _aligned_blocks = l; - } - - return result; -} - -#ifdef VMS -struct vms_malloc_data -{ - int __malloc_initialized; - char *_heapbase; - malloc_info *_heapinfo; - size_t heapsize; - size_t _heapindex; - size_t _heaplimit; - size_t _chunks_used; - size_t _bytes_used; - size_t _chunks_free; - size_t _bytes_free; -} ____vms_malloc_data[] = -{ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -struct vms_core_routines -{ - __ptr_t (*__morecore) __P ((ptrdiff_t increment)); - __ptr_t (*__lesscore) __P ((__ptr_t address, ptrdiff_t increment)); -} ____vms_core_routines[] = -{ - { __vms_initial_morecore, __vms_initial_lesscore }, - { __default_morecore, __default_lesscore }, - { 0, 0 } -}; - -static int current_vms_data = -1; -static int current_vms_core_routines = 0; - -static void use_vms_core_routines (int i) -{ - current_vms_core_routines = i; - current_vms_data = i; -} - -static void use_vms_data (int i) -{ - use_vms_core_routines (i); - __malloc_initialized = ____vms_malloc_data[i].__malloc_initialized; - _heapbase = ____vms_malloc_data[i]._heapbase; - _heapinfo = ____vms_malloc_data[i]._heapinfo; - heapsize = ____vms_malloc_data[i].heapsize; - _heapindex = ____vms_malloc_data[i]._heapindex; - _heaplimit = ____vms_malloc_data[i]._heaplimit; - _chunks_used = ____vms_malloc_data[i]._chunks_used; - _bytes_used = ____vms_malloc_data[i]._bytes_used; - _chunks_free = ____vms_malloc_data[i]._chunks_free; - _bytes_free = ____vms_malloc_data[i]._bytes_free; -} - -static void store_vms_data (int i) -{ - ____vms_malloc_data[i].__malloc_initialized = __malloc_initialized; - ____vms_malloc_data[i]._heapbase = _heapbase; - ____vms_malloc_data[i]._heapinfo = _heapinfo; - ____vms_malloc_data[i].heapsize = heapsize; - ____vms_malloc_data[i]._heapindex = _heapindex; - ____vms_malloc_data[i]._heaplimit = _heaplimit; - ____vms_malloc_data[i]._chunks_used = _chunks_used; - ____vms_malloc_data[i]._bytes_used = _bytes_used; - ____vms_malloc_data[i]._chunks_free = _chunks_free; - ____vms_malloc_data[i]._bytes_free = _bytes_free; -} - -static void store_current_vms_data () -{ - switch (current_vms_data) - { - case 0: - case 1: - store_vms_data (current_vms_data); - break; - } -} - -__ptr_t __vms_morecore (increment) - ptrdiff_t increment; -{ - return - (*____vms_core_routines[current_vms_core_routines].__morecore) (increment); -} - -__ptr_t __vms_lesscore (ptr, increment) - __ptr_t ptr; - ptrdiff_t increment; -{ - return - (*____vms_core_routines[current_vms_core_routines].__lesscore) (ptr,increment); -} - -__ptr_t __vms_malloc (size) - size_t size; -{ - __ptr_t result; - int old_current_vms_data = current_vms_data; - - __malloc_hook = 0; - - store_current_vms_data (); - - if (____vms_malloc_data[0]._heapbase != 0) - use_vms_data (0); - else - use_vms_core_routines (0); - result = malloc (size); - store_vms_data (0); - if (result == NULL) - { - use_vms_data (1); - result = malloc (size); - store_vms_data (1); - vms_out_initial = 1; - } - __malloc_hook = __vms_malloc; - if (old_current_vms_data != -1) - use_vms_data (current_vms_data); - return result; -} - -void __vms_free (ptr) - __ptr_t ptr; -{ - int old_current_vms_data = current_vms_data; - - __free_hook = 0; - - store_current_vms_data (); - - if (ptr >= vms_initial_buffer && ptr <= vms_end_brk) - { - use_vms_data (0); - free (ptr); - store_vms_data (0); - } - else - { - use_vms_data (1); - free (ptr); - store_vms_data (1); - if (_chunks_free == 0 && _chunks_used == 0) - vms_out_initial = 0; - } - __free_hook = __vms_free; - if (old_current_vms_data != -1) - use_vms_data (current_vms_data); -} - -__ptr_t __vms_realloc (ptr, size) - __ptr_t ptr; - size_t size; -{ - __ptr_t result; - int old_current_vms_data = current_vms_data; - - __realloc_hook = 0; - - store_current_vms_data (); - - if (ptr >= vms_initial_buffer && ptr <= vms_end_brk) - { - use_vms_data (0); - result = realloc (ptr, size); - store_vms_data (0); - } - else - { - use_vms_data (1); - result = realloc (ptr, size); - store_vms_data (1); - } - __realloc_hook = __vms_realloc; - if (old_current_vms_data != -1) - use_vms_data (current_vms_data); - return result; -} -#endif /* VMS */ -/* Standard debugging hooks for `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -/* Old hook values. */ -static void (*old_free_hook) __P ((__ptr_t ptr)); -static __ptr_t (*old_malloc_hook) __P ((size_t size)); -static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, size_t size)); - -/* Function to call when something awful happens. */ -static void (*abortfunc) __P ((void)); - -/* Arbitrary magical numbers. */ -#define MAGICWORD 0xfedabeeb -#define MAGICBYTE ((char) 0xd7) - -struct hdr - { - size_t size; /* Exact size requested by user. */ - unsigned long int magic; /* Magic number to check header integrity. */ - }; - -static void checkhdr __P ((__const struct hdr *)); -static void -checkhdr (hdr) - __const struct hdr *hdr; -{ - if (hdr->magic != MAGICWORD || ((char *) &hdr[1])[hdr->size] != MAGICBYTE) - (*abortfunc) (); -} - -static void freehook __P ((__ptr_t)); -static void -freehook (ptr) - __ptr_t ptr; -{ - struct hdr *hdr = ((struct hdr *) ptr) - 1; - checkhdr (hdr); - hdr->magic = 0; - __free_hook = old_free_hook; - free (hdr); - __free_hook = freehook; -} - -static __ptr_t mallochook __P ((size_t)); -static __ptr_t -mallochook (size) - size_t size; -{ - struct hdr *hdr; - - __malloc_hook = old_malloc_hook; - hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); - __malloc_hook = mallochook; - if (hdr == NULL) - return NULL; - - hdr->size = size; - hdr->magic = MAGICWORD; - ((char *) &hdr[1])[size] = MAGICBYTE; - return (__ptr_t) (hdr + 1); -} - -static __ptr_t reallochook __P ((__ptr_t, size_t)); -static __ptr_t -reallochook (ptr, size) - __ptr_t ptr; - size_t size; -{ - struct hdr *hdr = ((struct hdr *) ptr) - 1; - - checkhdr (hdr); - __free_hook = old_free_hook; - __malloc_hook = old_malloc_hook; - __realloc_hook = old_realloc_hook; - hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1); - __free_hook = freehook; - __malloc_hook = mallochook; - __realloc_hook = reallochook; - if (hdr == NULL) - return NULL; - - hdr->size = size; - ((char *) &hdr[1])[size] = MAGICBYTE; - return (__ptr_t) (hdr + 1); -} - -int -mcheck (func) - void (*func) __P ((void)); -{ - extern void abort __P ((void)); - static int mcheck_used = 0; - - abortfunc = (func != NULL) ? func : abort; - - /* These hooks may not be safely inserted if malloc is already in use. */ - if (!__malloc_initialized && !mcheck_used) - { - old_free_hook = __free_hook; - __free_hook = freehook; - old_malloc_hook = __malloc_hook; - __malloc_hook = mallochook; - old_realloc_hook = __realloc_hook; - __realloc_hook = reallochook; - mcheck_used = 1; - } - - return mcheck_used ? 0 : -1; -} -/* More debugging hooks for `malloc'. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. - Written April 2, 1991 by John Gilmore of Cygnus Support. - Based on mcheck.c by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -#include <stdio.h> - -#ifndef __GNU_LIBRARY__ -extern char *getenv (); -#else -#include <stdlib.h> -#endif - -static FILE *mallstream; -static char mallenv[]= "MALLOC_TRACE"; -static char mallbuf[BUFSIZ]; /* Buffer for the output. */ - -/* Address to breakpoint on accesses to... */ -__ptr_t mallwatch; - -/* Old hook values. */ -static __ptr_t (*tr_old_morecore) __P ((ptrdiff_t increment)); -static __ptr_t (*tr_old_lesscore) __P ((__ptr_t ptr, ptrdiff_t increment)); -static void (*tr_old_free_hook) __P ((__ptr_t ptr)); -static __ptr_t (*tr_old_malloc_hook) __P ((size_t size)); -static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, size_t size)); - -/* This function is called when the block being alloc'd, realloc'd, or - freed has an address matching the variable "mallwatch". In a debugger, - set "mallwatch" to the address of interest, then put a breakpoint on - tr_break. */ - -void tr_break __P ((void)); -void -tr_break () -{ -} - -static void tr_freehook __P ((__ptr_t)); -static void -tr_freehook (ptr) - __ptr_t ptr; -{ - fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */ - if (ptr == mallwatch) - tr_break (); - __free_hook = tr_old_free_hook; - free (ptr); - __free_hook = tr_freehook; -} - -static __ptr_t tr_morecore __P ((ptrdiff_t)); -static __ptr_t -tr_morecore (increment) - ptrdiff_t increment; -{ - __ptr_t p; - - __morecore = tr_old_morecore; - p = (__ptr_t) (*__morecore) (increment); - __morecore = tr_morecore; - - fprintf (mallstream, "$ %p %d\n", p, increment); - - return p; -} - -static __ptr_t tr_lesscore __P ((__ptr_t, ptrdiff_t)); -static __ptr_t -tr_lesscore (ptr, increment) - __ptr_t ptr; - ptrdiff_t increment; -{ - __ptr_t p; - - __lesscore = tr_old_lesscore; - p = (__ptr_t) (*__lesscore) (ptr, increment); - __lesscore = tr_lesscore; - - fprintf (mallstream, "* %p (%p, %d)\n", p, ptr, increment); - - return p; -} - -static __ptr_t tr_mallochook __P ((size_t)); -static __ptr_t -tr_mallochook (size) - size_t size; -{ - __ptr_t hdr; - - __malloc_hook = tr_old_malloc_hook; - hdr = (__ptr_t) malloc (size); - __malloc_hook = tr_mallochook; - - /* We could be printing a NULL here; that's OK. */ - fprintf (mallstream, "+ %p %x\n", hdr, size); - - if (hdr == mallwatch) - tr_break (); - - return hdr; -} - -static __ptr_t tr_reallochook __P ((__ptr_t, size_t)); -static __ptr_t -tr_reallochook (ptr, size) - __ptr_t ptr; - size_t size; -{ - __ptr_t hdr; - - if (ptr == mallwatch) - tr_break (); - - __free_hook = tr_old_free_hook; - __malloc_hook = tr_old_malloc_hook; - __realloc_hook = tr_old_realloc_hook; - hdr = (__ptr_t) realloc (ptr, size); - __free_hook = tr_freehook; - __malloc_hook = tr_mallochook; - __realloc_hook = tr_reallochook; - if (hdr == NULL) - /* Failed realloc. */ - fprintf (mallstream, "! %p %x\n", ptr, size); - else - fprintf (mallstream, "< %p\n> %p %x\n", ptr, hdr, size); - - if (hdr == mallwatch) - tr_break (); - - return hdr; -} - -/* We enable tracing if either the environment variable MALLOC_TRACE - is set, or if the variable mallwatch has been patched to an address - that the debugging user wants us to stop on. When patching mallwatch, - don't forget to set a breakpoint on tr_break! */ - -void -mtrace () -{ - char *mallfile; - - mallfile = getenv (mallenv); - if (mallfile != NULL || mallwatch != NULL) - { - mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w"); - if (mallstream != NULL) - { - /* Be sure it doesn't malloc its buffer! */ - setbuf (mallstream, mallbuf); - fprintf (mallstream, "= Start\n"); -#if defined(emacs) && defined(VMS) - fprintf (mallstream, "= Initial buffer spans %p -- %p\n", - vms_initial_buffer, vms_end_brk + 1); -#endif - tr_old_morecore = __morecore; - __morecore = tr_morecore; - tr_old_lesscore = __lesscore; - __lesscore = tr_lesscore; - tr_old_free_hook = __free_hook; - __free_hook = tr_freehook; - tr_old_malloc_hook = __malloc_hook; - __malloc_hook = tr_mallochook; - tr_old_realloc_hook = __realloc_hook; - __realloc_hook = tr_reallochook; - } - } -} -/* Access the statistics maintained by `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include <malloc.h> -#endif - -struct mstats -mstats () -{ - struct mstats result; - - result.bytes_total = (char *) (*__morecore) (0) - _heapbase; - result.chunks_used = _chunks_used; - result.bytes_used = _bytes_used; - result.chunks_free = _chunks_free; - result.bytes_free = _bytes_free; - return result; -} |
