14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #if defined(_UWIN) && defined(_BLD_ast)
234887Schin
_STUB_vmprofile()244887Schin void _STUB_vmprofile(){}
254887Schin
264887Schin #else
274887Schin
284887Schin #include "vmhdr.h"
294887Schin
304887Schin /* Method to profile space usage.
314887Schin **
324887Schin ** Written by Kiem-Phong Vo, kpv@research.att.com, 03/23/94.
334887Schin */
344887Schin
354887Schin #define PFHASH(pf) ((pf)->data.data.hash)
364887Schin #define PFVM(pf) ((pf)->data.data.vm)
374887Schin #define PFFILE(pf) ((pf)->data.data.fm.file)
384887Schin #define PFLINE(pf) ((pf)->line)
394887Schin #define PFNAME(pf) ((pf)->data.f)
404887Schin #define PFNALLOC(pf) ((pf)->data.data.nalloc)
414887Schin #define PFALLOC(pf) ((pf)->data.data.alloc)
424887Schin #define PFNFREE(pf) ((pf)->data.data.nfree)
434887Schin #define PFFREE(pf) ((pf)->data.data.free)
444887Schin #define PFREGION(pf) ((pf)->data.data.region)
454887Schin #define PFMAX(pf) ((pf)->data.data.fm.max)
464887Schin
474887Schin typedef struct _pfdata_s Pfdata_t;
484887Schin struct _pfdata_s
494887Schin { Vmulong_t hash; /* hash value */
504887Schin union
514887Schin { char* file; /* file name */
524887Schin Vmulong_t max; /* max busy space for region */
534887Schin } fm;
544887Schin Vmalloc_t* vm; /* region alloc from */
554887Schin Pfobj_t* region; /* pointer to region record */
564887Schin Vmulong_t nalloc; /* number of alloc calls */
574887Schin Vmulong_t alloc; /* amount allocated */
584887Schin Vmulong_t nfree; /* number of free calls */
594887Schin Vmulong_t free; /* amount freed */
604887Schin };
614887Schin struct _pfobj_s
624887Schin { Pfobj_t* next; /* next in linked list */
634887Schin int line; /* line #, 0 for name holder */
644887Schin union
654887Schin {
664887Schin Pfdata_t data;
674887Schin char f[1]; /* actual file name */
684887Schin } data;
694887Schin };
704887Schin
714887Schin static Pfobj_t** Pftable; /* hash table */
724887Schin #define PFTABLE 1019 /* table size */
734887Schin static Vmalloc_t* Vmpf; /* heap for our own use */
744887Schin
754887Schin #if __STD_C
pfsearch(Vmalloc_t * vm,const char * file,int line)764887Schin static Pfobj_t* pfsearch(Vmalloc_t* vm, const char* file, int line)
774887Schin #else
784887Schin static Pfobj_t* pfsearch(vm, file, line)
794887Schin Vmalloc_t* vm; /* region allocating from */
804887Schin const char* file; /* the file issuing the allocation request */
814887Schin int line; /* line number */
824887Schin #endif
834887Schin {
844887Schin reg Pfobj_t *pf, *last;
854887Schin reg Vmulong_t h;
864887Schin reg int n;
874887Schin reg const char* cp;
884887Schin
894887Schin if(!Vmpf && !(Vmpf = vmopen(Vmdcheap,Vmpool,0)) )
904887Schin return NIL(Pfobj_t*);
914887Schin
924887Schin /* make hash table; PFTABLE'th slot hold regions' records */
934887Schin if(!Pftable)
944887Schin { if(!(Pftable = (Pfobj_t**)vmalloc(Vmheap,(PFTABLE+1)*sizeof(Pfobj_t*))) )
954887Schin return NIL(Pfobj_t*);
964887Schin for(n = PFTABLE; n >= 0; --n)
974887Schin Pftable[n] = NIL(Pfobj_t*);
984887Schin }
994887Schin
1004887Schin /* see if it's there with a combined hash value of vm,file,line */
1014887Schin h = line + (((Vmulong_t)vm)>>4);
1024887Schin for(cp = file; *cp; ++cp)
1034887Schin h += (h<<7) + ((*cp)&0377) + 987654321L;
1044887Schin n = (int)(h%PFTABLE);
1054887Schin for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; last = pf, pf = pf->next)
1064887Schin if(PFLINE(pf) == line && PFVM(pf) == vm && strcmp(PFFILE(pf),file) == 0)
1074887Schin break;
1084887Schin
1094887Schin /* insert if not there yet */
1104887Schin if(!pf)
1114887Schin { reg Pfobj_t* fn;
1124887Schin reg Pfobj_t* pfvm;
1134887Schin reg Vmulong_t hn;
1144887Schin
1154887Schin /* first get/construct the file name slot */
1164887Schin hn = 0;
1174887Schin for(cp = file; *cp; ++cp)
1184887Schin hn += (hn<<7) + ((*cp)&0377) + 987654321L;
1194887Schin n = (int)(hn%PFTABLE);
1204887Schin for(fn = Pftable[n]; fn; fn = fn->next)
1214887Schin if(PFLINE(fn) < 0 && strcmp(PFNAME(fn),file) == 0)
1224887Schin break;
1234887Schin if(!fn)
1244887Schin { reg size_t s;
1254887Schin s = sizeof(Pfobj_t) - sizeof(Pfdata_t) + strlen(file) + 1;
1264887Schin if(!(fn = (Pfobj_t*)vmalloc(Vmheap,s)) )
1274887Schin return NIL(Pfobj_t*);
1284887Schin fn->next = Pftable[n];
1294887Schin Pftable[n] = fn;
1304887Schin PFLINE(fn) = -1;
1314887Schin strcpy(PFNAME(fn),file);
1324887Schin }
1334887Schin
1344887Schin /* get region record; note that these are ordered by vm */
1354887Schin last = NIL(Pfobj_t*);
1364887Schin for(pfvm = Pftable[PFTABLE]; pfvm; last = pfvm, pfvm = pfvm->next)
1374887Schin if(vm >= PFVM(pfvm))
1384887Schin break;
1394887Schin if(!pfvm || PFVM(pfvm) > vm)
1404887Schin { if(!(pfvm = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
1414887Schin return NIL(Pfobj_t*);
1424887Schin if(last)
1434887Schin { pfvm->next = last->next;
1444887Schin last->next = pfvm;
1454887Schin }
1464887Schin else
1474887Schin { pfvm->next = Pftable[PFTABLE];
1484887Schin Pftable[PFTABLE] = pfvm;
1494887Schin }
1504887Schin PFNALLOC(pfvm) = PFALLOC(pfvm) = 0;
1514887Schin PFNFREE(pfvm) = PFFREE(pfvm) = 0;
1524887Schin PFMAX(pfvm) = 0;
1534887Schin PFVM(pfvm) = vm;
1544887Schin PFLINE(pfvm) = 0;
1554887Schin }
1564887Schin
1574887Schin if(!(pf = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
1584887Schin return NIL(Pfobj_t*);
1594887Schin n = (int)(h%PFTABLE);
1604887Schin pf->next = Pftable[n];
1614887Schin Pftable[n] = pf;
1624887Schin PFLINE(pf) = line;
1634887Schin PFFILE(pf) = PFNAME(fn);
1644887Schin PFREGION(pf) = pfvm;
1654887Schin PFVM(pf) = vm;
1664887Schin PFNALLOC(pf) = 0;
1674887Schin PFALLOC(pf) = 0;
1684887Schin PFNFREE(pf) = 0;
1694887Schin PFFREE(pf) = 0;
1704887Schin PFHASH(pf) = h;
1714887Schin }
1724887Schin else if(last) /* do a move-to-front */
1734887Schin { last->next = pf->next;
1744887Schin pf->next = Pftable[n];
1754887Schin Pftable[n] = pf;
1764887Schin }
1774887Schin
1784887Schin return pf;
1794887Schin }
1804887Schin
1814887Schin #if __STD_C
pfclose(Vmalloc_t * vm)1824887Schin static void pfclose(Vmalloc_t* vm)
1834887Schin #else
1844887Schin static void pfclose(vm)
1854887Schin Vmalloc_t* vm;
1864887Schin #endif
1874887Schin {
1884887Schin reg int n;
1894887Schin reg Pfobj_t *pf, *next, *last;
1904887Schin
1914887Schin /* free all records related to region vm */
1924887Schin for(n = PFTABLE; n >= 0; --n)
1934887Schin { for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; )
1944887Schin { next = pf->next;
1954887Schin
1964887Schin if(PFLINE(pf) >= 0 && PFVM(pf) == vm)
1974887Schin { if(last)
1984887Schin last->next = next;
1994887Schin else Pftable[n] = next;
2004887Schin vmfree(Vmpf,pf);
2014887Schin }
2024887Schin else last = pf;
2034887Schin
2044887Schin pf = next;
2054887Schin }
2064887Schin }
2074887Schin }
2084887Schin
2094887Schin #if __STD_C
pfsetinfo(Vmalloc_t * vm,Vmuchar_t * data,size_t size,const char * file,int line)2104887Schin static void pfsetinfo(Vmalloc_t* vm, Vmuchar_t* data, size_t size, const char* file, int line)
2114887Schin #else
2124887Schin static void pfsetinfo(vm, data, size, file, line)
2134887Schin Vmalloc_t* vm;
2144887Schin Vmuchar_t* data;
2154887Schin size_t size;
2164887Schin const char* file;
2174887Schin int line;
2184887Schin #endif
2194887Schin {
2204887Schin reg Pfobj_t* pf;
2214887Schin reg Vmulong_t s;
2224887Schin
2234887Schin /* let vmclose knows that there are records for region vm */
2244887Schin _Vmpfclose = pfclose;
2254887Schin
2264887Schin if(!file || line <= 0)
2274887Schin { file = "";
2284887Schin line = 0;
2294887Schin }
2304887Schin
2314887Schin if((pf = pfsearch(vm,file,line)) )
2324887Schin { PFALLOC(pf) += size;
2334887Schin PFNALLOC(pf) += 1;
2344887Schin }
2354887Schin PFOBJ(data) = pf;
2364887Schin PFSIZE(data) = size;
2374887Schin
2384887Schin if(pf)
2394887Schin { /* update region statistics */
2404887Schin pf = PFREGION(pf);
2414887Schin PFALLOC(pf) += size;
2424887Schin PFNALLOC(pf) += 1;
2434887Schin if((s = PFALLOC(pf) - PFFREE(pf)) > PFMAX(pf) )
2444887Schin PFMAX(pf) = s;
2454887Schin }
2464887Schin }
2474887Schin
2484887Schin /* sort by file names and line numbers */
2494887Schin #if __STD_C
pfsort(Pfobj_t * pf)2504887Schin static Pfobj_t* pfsort(Pfobj_t* pf)
2514887Schin #else
2524887Schin static Pfobj_t* pfsort(pf)
2534887Schin Pfobj_t* pf;
2544887Schin #endif
2554887Schin {
2564887Schin reg Pfobj_t *one, *two, *next;
2574887Schin reg int cmp;
2584887Schin
2594887Schin if(!pf->next)
2604887Schin return pf;
2614887Schin
2624887Schin /* partition to two equal size lists */
2634887Schin one = two = NIL(Pfobj_t*);
2644887Schin while(pf)
2654887Schin { next = pf->next;
2664887Schin pf->next = one;
2674887Schin one = pf;
2684887Schin
2694887Schin if((pf = next) )
2704887Schin { next = pf->next;
2714887Schin pf->next = two;
2724887Schin two = pf;
2734887Schin pf = next;
2744887Schin }
2754887Schin }
2764887Schin
2774887Schin /* sort and merge the lists */
2784887Schin one = pfsort(one);
2794887Schin two = pfsort(two);
2804887Schin for(pf = next = NIL(Pfobj_t*);; )
2814887Schin { /* make sure that the "<>" file comes first */
2824887Schin if(PFLINE(one) == 0 && PFLINE(two) == 0)
2834887Schin cmp = PFVM(one) > PFVM(two) ? 1 : -1;
2844887Schin else if(PFLINE(one) == 0)
2854887Schin cmp = -1;
2864887Schin else if(PFLINE(two) == 0)
2874887Schin cmp = 1;
2884887Schin else if((cmp = strcmp(PFFILE(one),PFFILE(two))) == 0)
2894887Schin { cmp = PFLINE(one) - PFLINE(two);
2904887Schin if(cmp == 0)
2914887Schin cmp = PFVM(one) > PFVM(two) ? 1 : -1;
2924887Schin }
2934887Schin
2944887Schin if(cmp < 0)
2954887Schin { if(!pf)
2964887Schin pf = one;
2974887Schin else next->next = one;
2984887Schin next = one;
2994887Schin if(!(one = one->next) )
3004887Schin { if(two)
3014887Schin next->next = two;
3024887Schin return pf;
3034887Schin }
3044887Schin }
3054887Schin else
3064887Schin { if(!pf)
3074887Schin pf = two;
3084887Schin else next->next = two;
3094887Schin next = two;
3104887Schin if(!(two = two->next) )
3114887Schin { if(one)
3124887Schin next->next = one;
3134887Schin return pf;
3144887Schin }
3154887Schin }
3164887Schin }
3174887Schin }
3184887Schin
3194887Schin #if __STD_C
pfsummary(char * buf,Vmulong_t na,Vmulong_t sa,Vmulong_t nf,Vmulong_t sf,Vmulong_t max,Vmulong_t size)3204887Schin static char* pfsummary(char* buf, Vmulong_t na, Vmulong_t sa,
3214887Schin Vmulong_t nf, Vmulong_t sf, Vmulong_t max, Vmulong_t size)
3224887Schin #else
3234887Schin static char* pfsummary(buf, na, sa, nf, sf, max, size)
3244887Schin char* buf;
3254887Schin Vmulong_t na;
3264887Schin Vmulong_t sa;
3274887Schin Vmulong_t nf;
3284887Schin Vmulong_t sf;
3294887Schin Vmulong_t max;
3304887Schin Vmulong_t size;
3314887Schin #endif
3324887Schin {
3334887Schin buf = (*_Vmstrcpy)(buf,"n_alloc", '=');
3344887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(na,-1), ':');
3354887Schin buf = (*_Vmstrcpy)(buf,"n_free", '=');
3364887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(nf,-1), ':');
3374887Schin buf = (*_Vmstrcpy)(buf,"s_alloc", '=');
3384887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sa,-1), ':');
3394887Schin buf = (*_Vmstrcpy)(buf,"s_free", '=');
3404887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sf,-1), ':');
3414887Schin if(max > 0)
3424887Schin { buf = (*_Vmstrcpy)(buf,"max_busy", '=');
3434887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(max,-1), ':');
3444887Schin buf = (*_Vmstrcpy)(buf,"extent", '=');
3454887Schin buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(size,-1), ':');
3464887Schin }
3474887Schin *buf++ = '\n';
3484887Schin
3494887Schin return buf;
3504887Schin }
3514887Schin
3524887Schin /* print profile data */
3534887Schin #if __STD_C
vmprofile(Vmalloc_t * vm,int fd)3544887Schin int vmprofile(Vmalloc_t* vm, int fd)
3554887Schin #else
3564887Schin int vmprofile(vm, fd)
3574887Schin Vmalloc_t* vm;
3584887Schin int fd;
3594887Schin #endif
3604887Schin {
3614887Schin reg Pfobj_t *pf, *list, *next, *last;
3624887Schin reg int n;
3634887Schin reg Vmulong_t nalloc, alloc, nfree, free;
3644887Schin reg Seg_t* seg;
3654887Schin char buf[1024], *bufp, *endbuf;
3664887Schin #define INITBUF() (bufp = buf, endbuf = buf+sizeof(buf)-128)
3674887Schin #define CHKBUF() (bufp >= endbuf ? (write(fd,buf,bufp-buf), bufp=buf) : bufp)
3684887Schin #define FLSBUF() (bufp > buf ? write(fd,buf,bufp-buf) : 0)
3694887Schin
3704887Schin if(fd < 0)
3714887Schin return -1;
3724887Schin
3734887Schin /* initialize functions from vmtrace.c that we use below */
3744887Schin if((n = vmtrace(-1)) >= 0)
3754887Schin vmtrace(n);
3764887Schin
3774887Schin alloc = free = nalloc = nfree = 0;
3784887Schin list = NIL(Pfobj_t*);
3794887Schin for(n = PFTABLE-1; n >= 0; --n)
3804887Schin { for(pf = Pftable[n], last = NIL(Pfobj_t*); pf; )
3814887Schin { next = pf->next;
3824887Schin
3834887Schin if(PFLINE(pf) < 0 || (vm && vm != PFVM(pf)) )
3844887Schin { last = pf;
3854887Schin goto next_pf;
3864887Schin }
3874887Schin
3884887Schin /* remove from hash table */
3894887Schin if(last)
3904887Schin last->next = next;
3914887Schin else Pftable[n] = next;
3924887Schin
3934887Schin /* put on output list */
3944887Schin pf->next = list;
3954887Schin list = pf;
3964887Schin nalloc += PFNALLOC(pf);
3974887Schin alloc += PFALLOC(pf);
3984887Schin nfree += PFNFREE(pf);
3994887Schin free += PFFREE(pf);
4004887Schin
4014887Schin next_pf:
4024887Schin pf = next;
4034887Schin }
4044887Schin }
4054887Schin
4064887Schin INITBUF();
4074887Schin bufp = (*_Vmstrcpy)(bufp,"ALLOCATION USAGE SUMMARY", ':');
4084887Schin bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
4094887Schin
4104887Schin /* print regions' summary data */
4114887Schin for(pf = Pftable[PFTABLE]; pf; pf = pf->next)
4124887Schin { if(vm && PFVM(pf) != vm)
4134887Schin continue;
4144887Schin alloc = 0;
4154887Schin for(seg = PFVM(pf)->data->seg; seg; seg = seg->next)
4164887Schin alloc += seg->extent;
4174887Schin bufp = (*_Vmstrcpy)(bufp,"region", '=');
4184887Schin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
4194887Schin bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
4204887Schin PFNFREE(pf),PFFREE(pf),PFMAX(pf),alloc);
4214887Schin }
4224887Schin
4234887Schin /* sort then output detailed profile */
4244887Schin list = pfsort(list);
4254887Schin for(pf = list; pf; )
4264887Schin { /* compute summary for file */
4274887Schin alloc = free = nalloc = nfree = 0;
4284887Schin for(last = pf; last; last = last->next)
4294887Schin { if(strcmp(PFFILE(last),PFFILE(pf)) != 0)
4304887Schin break;
4314887Schin nalloc += PFNALLOC(pf);
4324887Schin alloc += PFALLOC(last);
4334887Schin nfree += PFNFREE(last);
4344887Schin free += PFFREE(last);
4354887Schin }
4364887Schin CHKBUF();
4374887Schin bufp = (*_Vmstrcpy)(bufp,"file",'=');
4384887Schin bufp = (*_Vmstrcpy)(bufp,PFFILE(pf)[0] ? PFFILE(pf) : "<>" ,':');
4394887Schin bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
4404887Schin
4414887Schin while(pf != last) /* detailed data */
4424887Schin { CHKBUF();
4434887Schin bufp = (*_Vmstrcpy)(bufp,"\tline",'=');
4444887Schin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(PFLINE(pf),-1), ':');
4454887Schin bufp = (*_Vmstrcpy)(bufp, "region", '=');
4464887Schin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
4474887Schin bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
4484887Schin PFNFREE(pf),PFFREE(pf),0,0);
4494887Schin
4504887Schin /* reinsert into hash table */
4514887Schin next = pf->next;
4524887Schin n = (int)(PFHASH(pf)%PFTABLE);
4534887Schin pf->next = Pftable[n];
4544887Schin Pftable[n] = pf;
4554887Schin pf = next;
4564887Schin }
4574887Schin }
4584887Schin
4594887Schin FLSBUF();
4604887Schin return 0;
4614887Schin }
4624887Schin
4634887Schin #if __STD_C
pfalloc(Vmalloc_t * vm,size_t size)4644887Schin static Void_t* pfalloc(Vmalloc_t* vm, size_t size)
4654887Schin #else
4664887Schin static Void_t* pfalloc(vm, size)
4674887Schin Vmalloc_t* vm;
4684887Schin size_t size;
4694887Schin #endif
4704887Schin {
4714887Schin reg size_t s;
4724887Schin reg Void_t* data;
4734887Schin reg char* file;
4748462SApril.Chin@Sun.COM reg int line, local, inuse;
4754887Schin reg Void_t* func;
4764887Schin reg Vmdata_t* vd = vm->data;
4774887Schin
4784887Schin VMFLF(vm,file,line,func);
4798462SApril.Chin@Sun.COM SETINUSE(vd, inuse);
4804887Schin if(!(local = vd->mode&VM_TRUST) )
4814887Schin { GETLOCAL(vd, local);
4824887Schin if(ISLOCK(vd, local))
4838462SApril.Chin@Sun.COM { CLRINUSE(vd, inuse);
4844887Schin return NIL(Void_t*);
4858462SApril.Chin@Sun.COM }
4864887Schin SETLOCK(vd, local);
4874887Schin }
4884887Schin
4894887Schin s = ROUND(size,ALIGN) + PF_EXTRA;
4904887Schin if(!(data = KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
4914887Schin goto done;
4924887Schin
4934887Schin pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
4944887Schin
4954887Schin if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
4964887Schin { vm->file = file; vm->line = line; vm->func = func;
4974887Schin (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,0);
4984887Schin }
4994887Schin done:
5004887Schin CLRLOCK(vd, local);
5014887Schin ANNOUNCE(local, vm, VM_ALLOC, (Void_t*)data, vm->disc);
5028462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
5034887Schin return data;
5044887Schin }
5054887Schin
5064887Schin #if __STD_C
pffree(Vmalloc_t * vm,Void_t * data)5074887Schin static int pffree(Vmalloc_t* vm, Void_t* data)
5084887Schin #else
5094887Schin static int pffree(vm, data)
5104887Schin Vmalloc_t* vm;
5114887Schin Void_t* data;
5124887Schin #endif
5134887Schin {
5144887Schin reg Pfobj_t* pf;
5154887Schin reg size_t s;
5164887Schin reg char* file;
5178462SApril.Chin@Sun.COM reg int line, rv, local, inuse;
5184887Schin reg Void_t* func;
5194887Schin reg Vmdata_t* vd = vm->data;
5204887Schin
5214887Schin VMFLF(vm,file,line,func);
5224887Schin
5234887Schin if(!data)
5244887Schin return 0;
5254887Schin
5268462SApril.Chin@Sun.COM SETINUSE(vd, inuse);
5274887Schin if(!(local = vd->mode&VM_TRUST) )
5284887Schin { GETLOCAL(vd,local);
5294887Schin if(ISLOCK(vd,local))
5308462SApril.Chin@Sun.COM { CLRINUSE(vd, inuse);
5314887Schin return -1;
5328462SApril.Chin@Sun.COM }
5334887Schin SETLOCK(vd,local);
5344887Schin }
5354887Schin
5364887Schin if(KPVADDR(vm,data,Vmbest->addrf) != 0 )
5374887Schin { if(vm->disc->exceptf)
5384887Schin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
5394887Schin CLRLOCK(vd,0);
5408462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
5414887Schin return -1;
5424887Schin }
5434887Schin
5444887Schin pf = PFOBJ(data);
5454887Schin s = PFSIZE(data);
5464887Schin if(pf)
5474887Schin { PFNFREE(pf) += 1;
5484887Schin PFFREE(pf) += s;
5494887Schin pf = PFREGION(pf);
5504887Schin PFNFREE(pf) += 1;
5514887Schin PFFREE(pf) += s;
5524887Schin }
5534887Schin
5544887Schin if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
5554887Schin { vm->file = file; vm->line = line; vm->func = func;
5564887Schin (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),s,0);
5574887Schin }
5584887Schin
5594887Schin rv = KPVFREE((vm), (Void_t*)data, (*Vmbest->freef));
5604887Schin CLRLOCK(vd,local);
5614887Schin ANNOUNCE(local, vm, VM_FREE, data, vm->disc);
5628462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
5634887Schin return rv;
5644887Schin }
5654887Schin
5664887Schin #if __STD_C
pfresize(Vmalloc_t * vm,Void_t * data,size_t size,int type)5674887Schin static Void_t* pfresize(Vmalloc_t* vm, Void_t* data, size_t size, int type)
5684887Schin #else
5694887Schin static Void_t* pfresize(vm, data, size, type)
5704887Schin Vmalloc_t* vm;
5714887Schin Void_t* data;
5724887Schin size_t size;
5734887Schin int type;
5744887Schin #endif
5754887Schin {
5764887Schin reg Pfobj_t* pf;
5774887Schin reg size_t s;
5784887Schin reg size_t news;
5794887Schin reg Void_t* addr;
5804887Schin reg char* file;
5818462SApril.Chin@Sun.COM reg int line, local, inuse;
5824887Schin reg Void_t* func;
5834887Schin reg size_t oldsize;
5844887Schin reg Vmdata_t* vd = vm->data;
5854887Schin
5868462SApril.Chin@Sun.COM SETINUSE(vd, inuse);
5874887Schin if(!data)
5884887Schin { oldsize = 0;
5894887Schin addr = pfalloc(vm,size);
5904887Schin goto done;
5914887Schin }
5924887Schin if(size == 0)
5934887Schin { (void)pffree(vm,data);
5948462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
5954887Schin return NIL(Void_t*);
5964887Schin }
5974887Schin
5984887Schin VMFLF(vm,file,line,func);
5994887Schin if(!(local = vd->mode&VM_TRUST))
6004887Schin { GETLOCAL(vd, local);
6014887Schin if(ISLOCK(vd, local))
6028462SApril.Chin@Sun.COM { CLRINUSE(vd, inuse);
6034887Schin return NIL(Void_t*);
6048462SApril.Chin@Sun.COM }
6054887Schin SETLOCK(vd, local);
6064887Schin }
6074887Schin
6084887Schin if(KPVADDR(vm,data,Vmbest->addrf) != 0 )
6094887Schin { if(vm->disc->exceptf)
6104887Schin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
6114887Schin CLRLOCK(vd, local);
6128462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
6134887Schin return NIL(Void_t*);
6144887Schin }
6154887Schin
6164887Schin pf = PFOBJ(data);
6174887Schin s = oldsize = PFSIZE(data);
6184887Schin
6194887Schin news = ROUND(size,ALIGN) + PF_EXTRA;
6204887Schin if((addr = KPVRESIZE(vm,data,news,(type&~VM_RSZERO),Vmbest->resizef)) )
6214887Schin { if(pf)
6224887Schin { PFFREE(pf) += s;
6234887Schin PFNFREE(pf) += 1;
6244887Schin pf = PFREGION(pf);
6254887Schin PFFREE(pf) += s;
6264887Schin PFNFREE(pf) += 1;
6274887Schin pfsetinfo(vm,(Vmuchar_t*)addr,size,file,line);
6284887Schin }
6294887Schin
6304887Schin if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
6314887Schin { vm->file = file; vm->line = line; vm->func = func;
6324887Schin (*_Vmtrace)(vm,(Vmuchar_t*)data,(Vmuchar_t*)addr,size,0);
6334887Schin }
6344887Schin }
6354887Schin else if(pf) /* reset old info */
6364887Schin { PFALLOC(pf) -= s;
6374887Schin PFNALLOC(pf) -= 1;
6384887Schin pf = PFREGION(pf);
6394887Schin PFALLOC(pf) -= s;
6404887Schin PFNALLOC(pf) -= 1;
6414887Schin file = PFFILE(pf);
6424887Schin line = PFLINE(pf);
6434887Schin pfsetinfo(vm,(Vmuchar_t*)data,s,file,line);
6444887Schin }
6454887Schin
6464887Schin CLRLOCK(vd, local);
6474887Schin ANNOUNCE(local, vm, VM_RESIZE, (Void_t*)addr, vm->disc);
6484887Schin
6494887Schin done: if(addr && (type&VM_RSZERO) && oldsize < size)
6504887Schin { reg Vmuchar_t *d = (Vmuchar_t*)addr+oldsize, *ed = (Vmuchar_t*)addr+size;
6514887Schin do { *d++ = 0; } while(d < ed);
6524887Schin }
6534887Schin
6548462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
6554887Schin return addr;
6564887Schin }
6574887Schin
6584887Schin #if __STD_C
pfsize(Vmalloc_t * vm,Void_t * addr)6594887Schin static long pfsize(Vmalloc_t* vm, Void_t* addr)
6604887Schin #else
6614887Schin static long pfsize(vm, addr)
6624887Schin Vmalloc_t* vm;
6634887Schin Void_t* addr;
6644887Schin #endif
6654887Schin {
6664887Schin return (*Vmbest->addrf)(vm,addr) != 0 ? -1L : (long)PFSIZE(addr);
6674887Schin }
6684887Schin
6694887Schin #if __STD_C
pfaddr(Vmalloc_t * vm,Void_t * addr)6704887Schin static long pfaddr(Vmalloc_t* vm, Void_t* addr)
6714887Schin #else
6724887Schin static long pfaddr(vm, addr)
6734887Schin Vmalloc_t* vm;
6744887Schin Void_t* addr;
6754887Schin #endif
6764887Schin {
6774887Schin return (*Vmbest->addrf)(vm,addr);
6784887Schin }
6794887Schin
6804887Schin #if __STD_C
pfcompact(Vmalloc_t * vm)6814887Schin static int pfcompact(Vmalloc_t* vm)
6824887Schin #else
6834887Schin static int pfcompact(vm)
6844887Schin Vmalloc_t* vm;
6854887Schin #endif
6864887Schin {
6874887Schin return (*Vmbest->compactf)(vm);
6884887Schin }
6894887Schin
6904887Schin #if __STD_C
pfalign(Vmalloc_t * vm,size_t size,size_t align)6914887Schin static Void_t* pfalign(Vmalloc_t* vm, size_t size, size_t align)
6924887Schin #else
6934887Schin static Void_t* pfalign(vm, size, align)
6944887Schin Vmalloc_t* vm;
6954887Schin size_t size;
6964887Schin size_t align;
6974887Schin #endif
6984887Schin {
6994887Schin reg size_t s;
7004887Schin reg Void_t* data;
7014887Schin reg char* file;
7028462SApril.Chin@Sun.COM reg int line, local, inuse;
7034887Schin reg Void_t* func;
7044887Schin reg Vmdata_t* vd = vm->data;
7054887Schin
7064887Schin VMFLF(vm,file,line,func);
7074887Schin
7088462SApril.Chin@Sun.COM SETINUSE(vd, inuse);
7094887Schin if(!(local = vd->mode&VM_TRUST) )
7104887Schin { GETLOCAL(vd,local);
7114887Schin if(ISLOCK(vd, local))
7128462SApril.Chin@Sun.COM { CLRINUSE(vd, inuse);
7134887Schin return NIL(Void_t*);
7148462SApril.Chin@Sun.COM }
7154887Schin SETLOCK(vd, local);
7164887Schin }
7174887Schin
7184887Schin s = (size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN)) + PF_EXTRA;
7194887Schin if(!(data = KPVALIGN(vm,s,align,Vmbest->alignf)) )
7204887Schin goto done;
7214887Schin
7224887Schin pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
7234887Schin
7244887Schin if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
7254887Schin { vm->file = file; vm->line = line; vm->func = func;
7264887Schin (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,align);
7274887Schin }
7284887Schin done:
7294887Schin CLRLOCK(vd, local);
7304887Schin ANNOUNCE(local, vm, VM_ALLOC, data, vm->disc);
7318462SApril.Chin@Sun.COM CLRINUSE(vd, inuse);
7324887Schin return data;
7334887Schin }
7344887Schin
7354887Schin static Vmethod_t _Vmprofile =
7364887Schin {
7374887Schin pfalloc,
7384887Schin pfresize,
7394887Schin pffree,
7404887Schin pfaddr,
7414887Schin pfsize,
7424887Schin pfcompact,
7434887Schin pfalign,
7444887Schin VM_MTPROFILE
7454887Schin };
7464887Schin
7474887Schin __DEFINE__(Vmethod_t*,Vmprofile,&_Vmprofile);
7484887Schin
7494887Schin #ifdef NoF
7504887Schin NoF(vmprofile)
7514887Schin #endif
7524887Schin
7534887Schin #endif
754