da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Method to profile space usage.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo, kpv@research.att.com, 03/23/94.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Pfobj_t* pfsearch(Vmalloc_t* vm, const char* file, int line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char* file; /* the file issuing the allocation request */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make hash table; PFTABLE'th slot hold regions' records */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(!(Pftable = (Pfobj_t**)vmalloc(Vmheap,(PFTABLE+1)*sizeof(Pfobj_t*))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n = PFTABLE; n >= 0; --n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if it's there with a combined hash value of vm,file,line */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (int)(h%PFTABLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; last = pf, pf = pf->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(PFLINE(pf) == line && PFVM(pf) == vm && strcmp(PFFILE(pf),file) == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* insert if not there yet */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first get/construct the file name slot */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = sizeof(Pfobj_t) - sizeof(Pfdata_t) + strlen(file) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* get region record; note that these are ordered by vm */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pfvm = Pftable[PFTABLE]; pfvm; last = pfvm, pfvm = pfvm->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(!(pfvm = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (int)(h%PFTABLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* free all records related to region vm */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n = PFTABLE; n >= 0; --n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void pfsetinfo(Vmalloc_t* vm, Vmuchar_t* data, size_t size, const char* file, int line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char* file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* let vmclose knows that there are records for region vm */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* update region statistics */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* sort by file names and line numbers */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* partition to two equal size lists */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* sort and merge the lists */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* make sure that the "<>" file comes first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* pfsummary(char* buf, Vmulong_t na, Vmulong_t sa,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmulong_t nf, Vmulong_t sf, Vmulong_t max, Vmulong_t size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* print profile data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INITBUF() (bufp = buf, endbuf = buf+sizeof(buf)-128)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CHKBUF() (bufp >= endbuf ? (write(fd,buf,bufp-buf), bufp=buf) : bufp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FLSBUF() (bufp > buf ? write(fd,buf,bufp-buf) : 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* initialize functions from vmtrace.c that we use below */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* remove from hash table */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* put on output list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp,"ALLOCATION USAGE SUMMARY", ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print regions' summary data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* sort then output detailed profile */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* compute summary for file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp,PFFILE(pf)[0] ? PFFILE(pf) : "<>" ,':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(PFLINE(pf),-1), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reinsert into hash table */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ANNOUNCE(local, vm, VM_ALLOC, (Void_t*)data, vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* pfresize(Vmalloc_t* vm, Void_t* data, size_t size, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((addr = KPVRESIZE(vm,data,news,(type&~VM_RSZERO),Vmbest->resizef)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm,(Vmuchar_t*)data,(Vmuchar_t*)addr,size,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ANNOUNCE(local, vm, VM_RESIZE, (Void_t*)addr, vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { reg Vmuchar_t *d = (Vmuchar_t*)addr+oldsize, *ed = (Vmuchar_t*)addr+size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do { *d++ = 0; } while(d < ed);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (*Vmbest->addrf)(vm,addr) != 0 ? -1L : (long)PFSIZE(addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* pfalign(Vmalloc_t* vm, size_t size, size_t align)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN)) + PF_EXTRA;