/* 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 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING. If not, write tothe 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 __cplusplusextern"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#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! */typedefunsignedintsize_t;typedefintptrdiff_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_tmalloc__P((size_t__size));/* Re-allocate the previously allocated block in __ptr_t, making the new block SIZE bytes long. */extern__ptr_trealloc__P((__ptr_t__ptr,size_t__size));/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */extern__ptr_tcalloc__P((size_t__nmemb,size_t__size));/* Free a block allocated by `malloc', `realloc' or `calloc'. */externvoidfree__P((__ptr_t__ptr));/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */extern__ptr_tmemalign__P((size_t__alignment,size_t__size));/* Allocate SIZE bytes on a page boundary. */extern__ptr_tvalloc__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'. */externvoid__vms_free__P((__ptr_t__ptr));#endif#ifdef _MALLOC_INTERNAL#include <stdio.h> /* Harmless, gets __GNU_LIBRARY__ defined. */#if defined(HAVE_CONFIG_H) || defined(emacs)#include <config.h>#endif#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. */typedefunion{/* 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. */inttype;union{struct{size_tnfree;/* Free fragments in a fragmented block. */size_tfirst;/* First free fragment of the block. */}frag;/* Size (in blocks) of a large cluster. */size_tsize;}info;}busy;/* Heap information for a free block (that may be the first of a free cluster). */struct{size_tsize;/* Size (in blocks) of a free cluster. */size_tnext;/* Index of next free cluster. */size_tprev;/* Index of previous free cluster. */}free;}malloc_info;/* Pointer to first block of the heap. */externchar*_heapbase;/* Table indexed by block number giving per-block information. */externmalloc_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. */externsize_t_heapindex;/* Limit of valid info table indices. */externsize_t_heaplimit;/* Doubly linked lists of free fragments. */structlist{structlist*next;structlist*prev;};/* Free list headers for each fragment size. */externstructlist_fraghead[];/* List of blocks allocated with `memalign' (or `valloc'). */structalignlist{structalignlist*next;__ptr_taligned;/* The address that memaligned returned. */__ptr_texact;/* The address that malloc returned. */};externstructalignlist*_aligned_blocks;/* Instrumentation. */externsize_t_chunks_used;externsize_t_bytes_used;externsize_t_chunks_free;externsize_t_bytes_free;/* Internal version of `free' used in `morecore' (malloc.c). */externvoid_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. */externvoid(*__after_morecore_hook)__P((void));/* If not NULL, this function is called after each time `__lesscore' is called to increase the data size. */externvoid(*__after_lesscore_hook)__P((void));/* Nonzero if `malloc' has been called and done its initialization. */externint__malloc_initialized;/* Hooks for debugging versions. */externvoid(*__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. */externintmcheck__P((void(*__func)__P((void))));/* Activate a standard collection of tracing hooks. */externvoidmtrace__P((void));/* Statistics available to the user. */structmstats{size_tbytes_total;/* Total size of the heap. */size_tchunks_used;/* Chunks allocated by the user. */size_tbytes_used;/* Byte total of user-allocated chunks. */size_tchunks_free;/* Chunks in the free list. */size_tbytes_free;/* Byte total of chunks in the free list. */};/* Pick up the current statistics. */externstructmstatsmstats__P((void));/* Call WARNFUN with a warning message when memory usage is high. */externvoidmemory_warnings__P((__ptr_t__start,void(*__warnfun)__P((__constchar*))));/* Relocating allocator. *//* Allocate SIZE bytes, and store the address in *HANDLEPTR. */extern__ptr_tr_alloc__P((__ptr_t*__handleptr,size_t__size));/* Free the storage allocated in HANDLEPTR. */externvoidr_alloc_free__P((__ptr_t*__handleptr));/* Adjust the block at HANDLEPTR to be SIZE bytes long. */extern__ptr_tr_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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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. */staticsize_theapsize;/* Search index in the info table. */size_t_heapindex;/* Limit of valid info table indices. */size_t_heaplimit;/* Free lists for each fragment size. */structlist_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_talign__P((size_t));static__ptr_talign(size)size_tsize;{__ptr_tresult;unsignedlongintadj;result=(*__morecore)(size);adj=(unsignedlongint)((unsignedlongint)((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)();returnresult;}/* Set everything up and remember that we have. */staticintinitialize__P((void));staticintinitialize(){#ifdef RL_DEBUGexternVMS_present_buffer();printf("__malloc_initialized = %d\n",__malloc_initialized);VMS_present_buffer();#endifheapsize=HEAP/BLOCKSIZE;_heapinfo=(malloc_info*)align(heapsize*sizeof(malloc_info));if(_heapinfo==NULL)return0;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;return1;}/* Get neatly aligned memory, initializing or growing the heap info table as necessary. */static__ptr_tmorecore__P((size_t));static__ptr_tmorecore(size)size_tsize;{__ptr_tresult;malloc_info*newinfo,*oldinfo;size_tnewsize;result=align(size);if(result==NULL)returnNULL;/* 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);returnNULL;}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);returnresult;}/* Allocate memory from the heap. */__ptr_tmalloc(size)size_tsize;{__ptr_tresult;size_tblock,blocks,lastblocks,start;registersize_ti;structlist*next;if(size==0)returnNULL;if(__malloc_hook!=NULL)return(*__malloc_hook)(size);if(!__malloc_initialized)if(!initialize())returnNULL;if(size<sizeof(structlist))size=sizeof(structlist);/* 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. */registersize_tlog=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=(unsignedlongint)((unsignedlongint)((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)returnNULL;/* Link all fragments but the first into the free list. */for(i=1;i<(size_t)(BLOCKSIZE>>log);++i){next=(structlist*)((char*)result+(i<<log));#ifdef RL_DEBUGprintf("DEBUG: malloc (%d): next = %p\n",size,next);#endifnext->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)returnNULL;block=BLOCK(result);_heapinfo[block].busy.type=0;_heapinfo[block].busy.info.size=blocks;++_chunks_used;_bytes_used+=blocks*BLOCKSIZE;returnresult;}}/* 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;}returnresult;}/* 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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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 VMSvoid(*__free_hook)__P((__ptr_t__ptr))=__vms_free;#elsevoid(*__free_hook)__P((__ptr_t__ptr));#endif/* List of blocks allocated by memalign. */structalignlist*_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_tptr;{inttype;size_tblock,blocks;registersize_ti;structlist*prev,*next;block=BLOCK(ptr);type=_heapinfo[block].busy.type;switch(type){case0:/* 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{doi=_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)){registersize_tbytes=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=(structlist*)((char*)ADDRESS(block)+(_heapinfo[block].busy.info.frag.first<<type));#ifdef RL_DEBUGprintf("_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);#endifif(_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));}elseif(_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_DEBUGprintf("There's a bug hiding here (%s:%d), so I will print some values\n",__FILE__,__LINE__);#endifnext=(structlist*)ptr;#ifdef RL_DEBUGprintf(" (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);#endifnext->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=(structlist*)ptr;_heapinfo[block].busy.info.frag.nfree=1;_heapinfo[block].busy.info.frag.first=(unsignedlongint)((unsignedlongint)((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. */voidfree(ptr)__ptr_tptr;{registerstructalignlist*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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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_trealloc(ptr,size)__ptr_tptr;size_tsize;{__ptr_tresult;inttype;size_tblock,blocks,oldlimit;if(size==0){free(ptr);returnmalloc(0);}elseif(ptr==NULL)returnmalloc(size);if(__realloc_hook!=NULL)return(*__realloc_hook)(ptr,size);block=BLOCK(ptr);type=_heapinfo[block].busy.type;switch(type){case0:/* 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);returnresult;}}/* 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;}elseif(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_tprevious=malloc((block-_heapindex)*BLOCKSIZE);(void)malloc(blocks*BLOCKSIZE);free(previous);}returnNULL;}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)returnNULL;memcpy(result,ptr,min(size,(size_t)1<<type));free(ptr);}break;}returnresult;}/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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_tcalloc(nmemb,size)registersize_tnmemb;registersize_tsize;{register__ptr_tresult=malloc(nmemb*size);if(result!=NULL)(void)memset(result,0,nmemb*size);returnresult;}/* 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with the GNU C Library; see the file COPYING. If not, write tothe 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#endifextern__ptr_t__sbrk__P((intincrement));#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))#endifintvms_out_initial=0;charvms_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_tincrement;{__ptr_tresult=NULL;__ptr_ttemp;/* It's far easier to make the alignment here than to make a kludge in align () */#ifdef RL_DEBUGprintf(">>>foo... %p...",vms_current_brk);#endifvms_current_brk+=(BLOCKSIZE-((unsignedlong)vms_current_brk&(BLOCKSIZE-1)))&(BLOCKSIZE-1);#ifdef RL_DEBUGprintf("bar... %p. (%d)\n",vms_current_brk,increment);#endiftemp=vms_current_brk+(int)increment;if(temp<=vms_end_brk){if(increment>=0)result=vms_current_brk;elseresult=temp;vms_current_brk=temp;}returnresult;}__ptr_t__vms_initial_lesscore(ptr,size)__ptr_tptr;ptrdiff_tsize;{if(ptr>=vms_initial_buffer&&ptr<vms_initial_buffer+VMS_ALLOCATION_SIZE){vms_current_brk=ptr;returnvms_current_brk;}returnvms_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... */staticcharvms_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 */staticchar*vms_brk_start=0;staticchar*vms_brk_end=0;staticchar*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_tincrement;{__ptr_tresult;#ifdef VMS__ptr_ttemp;#ifdef RL_DEBUGprintf("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: ");#endifif(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;elsevms_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_DEBUGprintf("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");returnNULL;}if(increment>0){result=vms_brk_current;temp=vms_brk_current+increment;if(temp>vms_brk_end){__ptr_tfoo;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_DEBUGprintf("__sbrk(%d) --> %p\n",increment,foo);#endifif(foo==(__ptr_t)-1)returnNULL;#ifdef RL_DEBUGprintf(" ");#endif}else{result=__sbrk(increment);if(result==(__ptr_t)-1)returnNULL;temp=result+increment;}vms_brk_end=__sbrk(0);}vms_brk_current=temp;#ifdef RL_DEBUGprintf("vms_brk_current = %p\n",vms_brk_current);printf(" vms_brk_end = %p\n",vms_brk_end);#endifreturnresult;}#ifdef RL_DEBUGprintf(" 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;}returnvms_brk_current;#else /* not VMS */result=__sbrk((int)increment);if(result==(__ptr_t)-1)returnNULL;returnresult;#endif /* VMS */}__ptr_t__default_lesscore(ptr,size)__ptr_tptr;ptrdiff_tsize;{#ifdef VMSif(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_DEBUGprintf("<<<bar... %p (%p (%p, %d))...",vms_brk_end,vms_brk_current,ptr,size);#endifvms_brk_end=__brk(vms_brk_end);#ifdef RL_DEBUGprintf("foo... %p.\n",vms_brk_end);#endif}returnvms_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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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__externsize_t__getpagesize__P((void));#else#if !defined(USG) && !defined(VMS)externsize_tgetpagesize__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. */#endifstaticsize_tpagesize;__ptr_tvalloc(size)size_tsize;{if(pagesize==0)pagesize=__getpagesize();returnmemalign(pagesize,size);}/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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_tmemalign(alignment,size)size_talignment;size_tsize;{__ptr_tresult;unsignedlongintadj;size=((size+alignment-1)/alignment)*alignment;result=malloc(size);if(result==NULL)returnNULL;adj=(unsignedlongint)((unsignedlongint)((char*)result-(char*)NULL))%alignment;if(adj!=0){structalignlist*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=(structalignlist*)malloc(sizeof(structalignlist));if(l==NULL){free(result);returnNULL;}}l->exact=result;result=l->aligned=(char*)result+alignment-adj;l->next=_aligned_blocks;_aligned_blocks=l;}returnresult;}#ifdef VMSstructvms_malloc_data{int__malloc_initialized;char*_heapbase;malloc_info*_heapinfo;size_theapsize;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}};structvms_core_routines{__ptr_t(*__morecore)__P((ptrdiff_tincrement));__ptr_t(*__lesscore)__P((__ptr_taddress,ptrdiff_tincrement));}____vms_core_routines[]={{__vms_initial_morecore,__vms_initial_lesscore},{__default_morecore,__default_lesscore},{0,0}};staticintcurrent_vms_data=-1;staticintcurrent_vms_core_routines=0;staticvoiduse_vms_core_routines(inti){current_vms_core_routines=i;current_vms_data=i;}staticvoiduse_vms_data(inti){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;}staticvoidstore_vms_data(inti){____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;}staticvoidstore_current_vms_data(){switch(current_vms_data){case0:case1:store_vms_data(current_vms_data);break;}}__ptr_t__vms_morecore(increment)ptrdiff_tincrement;{return(*____vms_core_routines[current_vms_core_routines].__morecore)(increment);}__ptr_t__vms_lesscore(ptr,increment)__ptr_tptr;ptrdiff_tincrement;{return(*____vms_core_routines[current_vms_core_routines].__lesscore)(ptr,increment);}__ptr_t__vms_malloc(size)size_tsize;{__ptr_tresult;intold_current_vms_data=current_vms_data;__malloc_hook=0;store_current_vms_data();if(____vms_malloc_data[0]._heapbase!=0)use_vms_data(0);elseuse_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);returnresult;}void__vms_free(ptr)__ptr_tptr;{intold_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_tptr;size_tsize;{__ptr_tresult;intold_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);returnresult;}#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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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. */staticvoid(*old_free_hook)__P((__ptr_tptr));static__ptr_t(*old_malloc_hook)__P((size_tsize));static__ptr_t(*old_realloc_hook)__P((__ptr_tptr,size_tsize));/* Function to call when something awful happens. */staticvoid(*abortfunc)__P((void));/* Arbitrary magical numbers. */#define MAGICWORD 0xfedabeeb#define MAGICBYTE ((char) 0xd7)structhdr{size_tsize;/* Exact size requested by user. */unsignedlongintmagic;/* Magic number to check header integrity. */};staticvoidcheckhdr__P((__conststructhdr*));staticvoidcheckhdr(hdr)__conststructhdr*hdr;{if(hdr->magic!=MAGICWORD||((char*)&hdr[1])[hdr->size]!=MAGICBYTE)(*abortfunc)();}staticvoidfreehook__P((__ptr_t));staticvoidfreehook(ptr)__ptr_tptr;{structhdr*hdr=((structhdr*)ptr)-1;checkhdr(hdr);hdr->magic=0;__free_hook=old_free_hook;free(hdr);__free_hook=freehook;}static__ptr_tmallochook__P((size_t));static__ptr_tmallochook(size)size_tsize;{structhdr*hdr;__malloc_hook=old_malloc_hook;hdr=(structhdr*)malloc(sizeof(structhdr)+size+1);__malloc_hook=mallochook;if(hdr==NULL)returnNULL;hdr->size=size;hdr->magic=MAGICWORD;((char*)&hdr[1])[size]=MAGICBYTE;return(__ptr_t)(hdr+1);}static__ptr_treallochook__P((__ptr_t,size_t));static__ptr_treallochook(ptr,size)__ptr_tptr;size_tsize;{structhdr*hdr=((structhdr*)ptr)-1;checkhdr(hdr);__free_hook=old_free_hook;__malloc_hook=old_malloc_hook;__realloc_hook=old_realloc_hook;hdr=(structhdr*)realloc((__ptr_t)hdr,sizeof(structhdr)+size+1);__free_hook=freehook;__malloc_hook=mallochook;__realloc_hook=reallochook;if(hdr==NULL)returnNULL;hdr->size=size;((char*)&hdr[1])[size]=MAGICBYTE;return(__ptr_t)(hdr+1);}intmcheck(func)void(*func)__P((void));{externvoidabort__P((void));staticintmcheck_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;}returnmcheck_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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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__externchar*getenv();#else#include <stdlib.h>#endifstaticFILE*mallstream;staticcharmallenv[]="MALLOC_TRACE";staticcharmallbuf[BUFSIZ];/* Buffer for the output. *//* Address to breakpoint on accesses to... */__ptr_tmallwatch;/* Old hook values. */static__ptr_t(*tr_old_morecore)__P((ptrdiff_tincrement));static__ptr_t(*tr_old_lesscore)__P((__ptr_tptr,ptrdiff_tincrement));staticvoid(*tr_old_free_hook)__P((__ptr_tptr));static__ptr_t(*tr_old_malloc_hook)__P((size_tsize));static__ptr_t(*tr_old_realloc_hook)__P((__ptr_tptr,size_tsize));/* 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. */voidtr_break__P((void));voidtr_break(){}staticvoidtr_freehook__P((__ptr_t));staticvoidtr_freehook(ptr)__ptr_tptr;{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_ttr_morecore__P((ptrdiff_t));static__ptr_ttr_morecore(increment)ptrdiff_tincrement;{__ptr_tp;__morecore=tr_old_morecore;p=(__ptr_t)(*__morecore)(increment);__morecore=tr_morecore;fprintf(mallstream,"$ %p %d\n",p,increment);returnp;}static__ptr_ttr_lesscore__P((__ptr_t,ptrdiff_t));static__ptr_ttr_lesscore(ptr,increment)__ptr_tptr;ptrdiff_tincrement;{__ptr_tp;__lesscore=tr_old_lesscore;p=(__ptr_t)(*__lesscore)(ptr,increment);__lesscore=tr_lesscore;fprintf(mallstream,"* %p (%p, %d)\n",p,ptr,increment);returnp;}static__ptr_ttr_mallochook__P((size_t));static__ptr_ttr_mallochook(size)size_tsize;{__ptr_thdr;__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();returnhdr;}static__ptr_ttr_reallochook__P((__ptr_t,size_t));static__ptr_ttr_reallochook(ptr,size)__ptr_tptr;size_tsize;{__ptr_thdr;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);elsefprintf(mallstream,"< %p\n> %p %x\n",ptr,hdr,size);if(hdr==mallwatch)tr_break();returnhdr;}/* 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! */voidmtrace(){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);#endiftr_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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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>#endifstructmstatsmstats(){structmstatsresult;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;returnresult;}