Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/vmalloc/vmprofile.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#if defined(_UWIN) && defined(_BLD_ast)
23
24
void _STUB_vmprofile(){}
25
26
#else
27
28
#include "vmhdr.h"
29
30
/* Method to profile space usage.
31
**
32
** Written by Kiem-Phong Vo, [email protected], 03/23/94.
33
*/
34
35
#define PFHASH(pf) ((pf)->data.data.hash)
36
#define PFVM(pf) ((pf)->data.data.vm)
37
#define PFFILE(pf) ((pf)->data.data.fm.file)
38
#define PFLINE(pf) ((pf)->line)
39
#define PFNAME(pf) ((pf)->data.f)
40
#define PFNALLOC(pf) ((pf)->data.data.nalloc)
41
#define PFALLOC(pf) ((pf)->data.data.alloc)
42
#define PFNFREE(pf) ((pf)->data.data.nfree)
43
#define PFFREE(pf) ((pf)->data.data.free)
44
#define PFREGION(pf) ((pf)->data.data.region)
45
#define PFMAX(pf) ((pf)->data.data.fm.max)
46
47
typedef struct _pfdata_s Pfdata_t;
48
struct _pfdata_s
49
{ Vmulong_t hash; /* hash value */
50
union
51
{ char* file; /* file name */
52
Vmulong_t max; /* max busy space for region */
53
} fm;
54
Vmalloc_t* vm; /* region alloc from */
55
Pfobj_t* region; /* pointer to region record */
56
Vmulong_t nalloc; /* number of alloc calls */
57
Vmulong_t alloc; /* amount allocated */
58
Vmulong_t nfree; /* number of free calls */
59
Vmulong_t free; /* amount freed */
60
};
61
struct _pfobj_s
62
{ Pfobj_t* next; /* next in linked list */
63
int line; /* line #, 0 for name holder */
64
union
65
{
66
Pfdata_t data;
67
char f[1]; /* actual file name */
68
} data;
69
};
70
71
static Pfobj_t** Pftable; /* hash table */
72
#define PFTABLE 1019 /* table size */
73
static Vmalloc_t* Vmpf; /* heap for our own use */
74
75
#if __STD_C
76
static Pfobj_t* pfsearch(Vmalloc_t* vm, char* file, int line)
77
#else
78
static Pfobj_t* pfsearch(vm, file, line)
79
Vmalloc_t* vm; /* region allocating from */
80
char* file; /* the file issuing the allocation request */
81
int line; /* line number */
82
#endif
83
{
84
reg Pfobj_t *pf, *last;
85
reg Vmulong_t h;
86
reg int n;
87
reg char *cp;
88
89
if(!Vmpf && !(Vmpf = vmopen(Vmdcheap,Vmpool,0)) )
90
return NIL(Pfobj_t*);
91
92
/* make hash table; PFTABLE'th slot hold regions' records */
93
if(!Pftable)
94
{ if(!(Pftable = (Pfobj_t**)vmalloc(Vmheap,(PFTABLE+1)*sizeof(Pfobj_t*))) )
95
return NIL(Pfobj_t*);
96
for(n = PFTABLE; n >= 0; --n)
97
Pftable[n] = NIL(Pfobj_t*);
98
}
99
100
/* see if it's there with a combined hash value of vm,file,line */
101
h = line + (((Vmulong_t)vm)>>4);
102
for(cp = file; *cp; ++cp)
103
h += (h<<7) + ((*cp)&0377) + 987654321L;
104
n = (int)(h%PFTABLE);
105
for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; last = pf, pf = pf->next)
106
if(PFLINE(pf) == line && PFVM(pf) == vm && strcmp(PFFILE(pf),file) == 0)
107
break;
108
109
/* insert if not there yet */
110
if(!pf)
111
{ reg Pfobj_t* fn;
112
reg Pfobj_t* pfvm;
113
reg Vmulong_t hn;
114
115
/* first get/construct the file name slot */
116
hn = 0;
117
for(cp = file; *cp; ++cp)
118
hn += (hn<<7) + ((*cp)&0377) + 987654321L;
119
n = (int)(hn%PFTABLE);
120
for(fn = Pftable[n]; fn; fn = fn->next)
121
if(PFLINE(fn) < 0 && strcmp(PFNAME(fn),file) == 0)
122
break;
123
if(!fn)
124
{ reg size_t s;
125
s = sizeof(Pfobj_t) - sizeof(Pfdata_t) + strlen(file) + 1;
126
if(!(fn = (Pfobj_t*)vmalloc(Vmheap,s)) )
127
return NIL(Pfobj_t*);
128
fn->next = Pftable[n];
129
Pftable[n] = fn;
130
PFLINE(fn) = -1;
131
strcpy(PFNAME(fn),file);
132
}
133
134
/* get region record; note that these are ordered by vm */
135
last = NIL(Pfobj_t*);
136
for(pfvm = Pftable[PFTABLE]; pfvm; last = pfvm, pfvm = pfvm->next)
137
if(vm >= PFVM(pfvm))
138
break;
139
if(!pfvm || PFVM(pfvm) > vm)
140
{ if(!(pfvm = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
141
return NIL(Pfobj_t*);
142
if(last)
143
{ pfvm->next = last->next;
144
last->next = pfvm;
145
}
146
else
147
{ pfvm->next = Pftable[PFTABLE];
148
Pftable[PFTABLE] = pfvm;
149
}
150
PFNALLOC(pfvm) = PFALLOC(pfvm) = 0;
151
PFNFREE(pfvm) = PFFREE(pfvm) = 0;
152
PFMAX(pfvm) = 0;
153
PFVM(pfvm) = vm;
154
PFLINE(pfvm) = 0;
155
}
156
157
if(!(pf = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
158
return NIL(Pfobj_t*);
159
n = (int)(h%PFTABLE);
160
pf->next = Pftable[n];
161
Pftable[n] = pf;
162
PFLINE(pf) = line;
163
PFFILE(pf) = PFNAME(fn);
164
PFREGION(pf) = pfvm;
165
PFVM(pf) = vm;
166
PFNALLOC(pf) = 0;
167
PFALLOC(pf) = 0;
168
PFNFREE(pf) = 0;
169
PFFREE(pf) = 0;
170
PFHASH(pf) = h;
171
}
172
else if(last) /* do a move-to-front */
173
{ last->next = pf->next;
174
pf->next = Pftable[n];
175
Pftable[n] = pf;
176
}
177
178
return pf;
179
}
180
181
#if __STD_C
182
static void pfclose(Vmalloc_t* vm)
183
#else
184
static void pfclose(vm)
185
Vmalloc_t* vm;
186
#endif
187
{
188
reg int n;
189
reg Pfobj_t *pf, *next, *last;
190
191
/* free all records related to region vm */
192
for(n = PFTABLE; n >= 0; --n)
193
{ for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; )
194
{ next = pf->next;
195
196
if(PFLINE(pf) >= 0 && PFVM(pf) == vm)
197
{ if(last)
198
last->next = next;
199
else Pftable[n] = next;
200
vmfree(Vmpf,pf);
201
}
202
else last = pf;
203
204
pf = next;
205
}
206
}
207
}
208
209
#if __STD_C
210
static void pfsetinfo(Vmalloc_t* vm, Vmuchar_t* data, size_t size, char* file, int line)
211
#else
212
static void pfsetinfo(vm, data, size, file, line)
213
Vmalloc_t* vm;
214
Vmuchar_t* data;
215
size_t size;
216
char* file;
217
int line;
218
#endif
219
{
220
reg Pfobj_t* pf;
221
reg Vmulong_t s;
222
223
/* let vmclose knows that there are records for region vm */
224
_Vmpfclose = pfclose;
225
226
if(!file || line <= 0)
227
{ file = "";
228
line = 0;
229
}
230
231
if((pf = pfsearch(vm,file,line)) )
232
{ PFALLOC(pf) += (Vmulong_t)size;
233
PFNALLOC(pf) += 1;
234
}
235
PFOBJ(data) = pf;
236
PFSIZE(data) = size;
237
238
if(pf)
239
{ /* update region statistics */
240
pf = PFREGION(pf);
241
PFALLOC(pf) += (Vmulong_t)size;
242
PFNALLOC(pf) += 1;
243
if((s = PFALLOC(pf) - PFFREE(pf)) > PFMAX(pf) )
244
PFMAX(pf) = s;
245
}
246
}
247
248
/* sort by file names and line numbers */
249
#if __STD_C
250
static Pfobj_t* pfsort(Pfobj_t* pf)
251
#else
252
static Pfobj_t* pfsort(pf)
253
Pfobj_t* pf;
254
#endif
255
{
256
reg Pfobj_t *one, *two, *next;
257
reg int cmp;
258
259
if(!pf->next)
260
return pf;
261
262
/* partition to two equal size lists */
263
one = two = NIL(Pfobj_t*);
264
while(pf)
265
{ next = pf->next;
266
pf->next = one;
267
one = pf;
268
269
if((pf = next) )
270
{ next = pf->next;
271
pf->next = two;
272
two = pf;
273
pf = next;
274
}
275
}
276
277
/* sort and merge the lists */
278
one = pfsort(one);
279
two = pfsort(two);
280
for(pf = next = NIL(Pfobj_t*);; )
281
{ /* make sure that the "<>" file comes first */
282
if(PFLINE(one) == 0 && PFLINE(two) == 0)
283
cmp = PFVM(one) > PFVM(two) ? 1 : -1;
284
else if(PFLINE(one) == 0)
285
cmp = -1;
286
else if(PFLINE(two) == 0)
287
cmp = 1;
288
else if((cmp = strcmp(PFFILE(one),PFFILE(two))) == 0)
289
{ cmp = PFLINE(one) - PFLINE(two);
290
if(cmp == 0)
291
cmp = PFVM(one) > PFVM(two) ? 1 : -1;
292
}
293
294
if(cmp < 0)
295
{ if(!pf)
296
pf = one;
297
else next->next = one;
298
next = one;
299
if(!(one = one->next) )
300
{ if(two)
301
next->next = two;
302
return pf;
303
}
304
}
305
else
306
{ if(!pf)
307
pf = two;
308
else next->next = two;
309
next = two;
310
if(!(two = two->next) )
311
{ if(one)
312
next->next = one;
313
return pf;
314
}
315
}
316
}
317
}
318
319
#if __STD_C
320
static char* pfsummary(char* buf, Vmulong_t na, Vmulong_t sa,
321
Vmulong_t nf, Vmulong_t sf, Vmulong_t max, Vmulong_t size)
322
#else
323
static char* pfsummary(buf, na, sa, nf, sf, max, size)
324
char* buf;
325
Vmulong_t na;
326
Vmulong_t sa;
327
Vmulong_t nf;
328
Vmulong_t sf;
329
Vmulong_t max;
330
Vmulong_t size;
331
#endif
332
{
333
buf = (*_Vmstrcpy)(buf,"n_alloc", '=');
334
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(na,-1), ':');
335
buf = (*_Vmstrcpy)(buf,"n_free", '=');
336
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(nf,-1), ':');
337
buf = (*_Vmstrcpy)(buf,"s_alloc", '=');
338
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sa,-1), ':');
339
buf = (*_Vmstrcpy)(buf,"s_free", '=');
340
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sf,-1), ':');
341
if(max > 0)
342
{ buf = (*_Vmstrcpy)(buf,"max_busy", '=');
343
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(max,-1), ':');
344
buf = (*_Vmstrcpy)(buf,"extent", '=');
345
buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(size,-1), ':');
346
}
347
*buf++ = '\n';
348
349
return buf;
350
}
351
352
/* print profile data */
353
#if __STD_C
354
int vmprofile(Vmalloc_t* vm, int fd)
355
#else
356
int vmprofile(vm, fd)
357
Vmalloc_t* vm;
358
int fd;
359
#endif
360
{
361
reg Pfobj_t *pf, *list, *next, *last;
362
reg int n;
363
reg Vmulong_t nalloc, alloc, nfree, free;
364
reg Seg_t *seg;
365
char buf[1024], *bufp, *endbuf;
366
#define INITBUF() (bufp = buf, endbuf = buf+sizeof(buf)-128)
367
#define CHKBUF() (bufp >= endbuf ? (write(fd,buf,bufp-buf), bufp=buf) : bufp)
368
#define FLSBUF() (bufp > buf ? write(fd,buf,bufp-buf) : 0)
369
370
if(fd < 0)
371
return -1;
372
373
/* initialize functions from vmtrace.c that we use below */
374
if((n = vmtrace(-1)) >= 0)
375
vmtrace(n);
376
377
alloc = free = nalloc = nfree = 0;
378
list = NIL(Pfobj_t*);
379
for(n = PFTABLE-1; n >= 0; --n)
380
{ for(pf = Pftable[n], last = NIL(Pfobj_t*); pf; )
381
{ next = pf->next;
382
383
if(PFLINE(pf) < 0 || (vm && vm != PFVM(pf)) )
384
{ last = pf;
385
goto next_pf;
386
}
387
388
/* remove from hash table */
389
if(last)
390
last->next = next;
391
else Pftable[n] = next;
392
393
/* put on output list */
394
pf->next = list;
395
list = pf;
396
nalloc += PFNALLOC(pf);
397
alloc += PFALLOC(pf);
398
nfree += PFNFREE(pf);
399
free += PFFREE(pf);
400
401
next_pf:
402
pf = next;
403
}
404
}
405
406
INITBUF();
407
bufp = (*_Vmstrcpy)(bufp,"ALLOCATION USAGE SUMMARY", ':');
408
bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
409
410
/* print regions' summary data */
411
for(pf = Pftable[PFTABLE]; pf; pf = pf->next)
412
{ if(vm && PFVM(pf) != vm)
413
continue;
414
alloc = 0;
415
for(seg = PFVM(pf)->data->seg; seg; seg = seg->next)
416
alloc += (Vmulong_t)seg->extent;
417
bufp = (*_Vmstrcpy)(bufp,"region", '=');
418
bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
419
bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
420
PFNFREE(pf),PFFREE(pf),PFMAX(pf),alloc);
421
}
422
423
/* sort then output detailed profile */
424
list = pfsort(list);
425
for(pf = list; pf; )
426
{ /* compute summary for file */
427
alloc = free = nalloc = nfree = 0;
428
for(last = pf; last; last = last->next)
429
{ if(strcmp(PFFILE(last),PFFILE(pf)) != 0)
430
break;
431
nalloc += PFNALLOC(pf);
432
alloc += PFALLOC(last);
433
nfree += PFNFREE(last);
434
free += PFFREE(last);
435
}
436
CHKBUF();
437
bufp = (*_Vmstrcpy)(bufp,"file",'=');
438
bufp = (*_Vmstrcpy)(bufp,PFFILE(pf)[0] ? PFFILE(pf) : "<>" ,':');
439
bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
440
441
while(pf != last) /* detailed data */
442
{ CHKBUF();
443
bufp = (*_Vmstrcpy)(bufp,"\tline",'=');
444
bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(PFLINE(pf),-1), ':');
445
bufp = (*_Vmstrcpy)(bufp, "region", '=');
446
bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
447
bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
448
PFNFREE(pf),PFFREE(pf),0,0);
449
450
/* reinsert into hash table */
451
next = pf->next;
452
n = (int)(PFHASH(pf)%PFTABLE);
453
pf->next = Pftable[n];
454
Pftable[n] = pf;
455
pf = next;
456
}
457
}
458
459
FLSBUF();
460
return 0;
461
}
462
463
#if __STD_C
464
static Void_t* pfalloc(Vmalloc_t* vm, size_t size, int local)
465
#else
466
static Void_t* pfalloc(vm, size, local)
467
Vmalloc_t* vm;
468
size_t size;
469
int local;
470
#endif
471
{
472
reg size_t s;
473
reg Void_t *data;
474
reg char *file;
475
reg int line;
476
reg Void_t *func;
477
reg Vmdata_t *vd = vm->data;
478
479
VMFLF(vm,file,line,func);
480
481
SETLOCK(vm, local);
482
483
s = ROUND(size,ALIGN) + PF_EXTRA;
484
if((data = KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
485
{ pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
486
487
if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
488
{ vm->file = file; vm->line = line; vm->func = func;
489
(*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,0);
490
}
491
}
492
493
CLRLOCK(vm, local);
494
495
return data;
496
}
497
498
#if __STD_C
499
static int pffree(Vmalloc_t* vm, Void_t* data, int local)
500
#else
501
static int pffree(vm, data, local)
502
Vmalloc_t* vm;
503
Void_t* data;
504
int local;
505
#endif
506
{
507
reg Pfobj_t *pf;
508
reg size_t s;
509
reg char *file;
510
reg int line, rv;
511
reg Void_t *func;
512
reg Vmdata_t *vd = vm->data;
513
514
VMFLF(vm,file,line,func);
515
516
if(!data)
517
return 0;
518
519
SETLOCK(vm,local);
520
521
/**/ASSERT(KPVADDR(vm, data, Vmbest->addrf) == 0 );
522
pf = PFOBJ(data);
523
s = PFSIZE(data);
524
if(pf)
525
{ PFNFREE(pf) += 1;
526
PFFREE(pf) += (Vmulong_t)s;
527
pf = PFREGION(pf);
528
PFNFREE(pf) += 1;
529
PFFREE(pf) += (Vmulong_t)s;
530
}
531
532
if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
533
{ vm->file = file; vm->line = line; vm->func = func;
534
(*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),s,0);
535
}
536
537
rv = KPVFREE((vm), (Void_t*)data, (*Vmbest->freef));
538
539
CLRLOCK(vm, local);
540
541
return rv;
542
}
543
544
#if __STD_C
545
static Void_t* pfresize(Vmalloc_t* vm, Void_t* data, size_t size, int type, int local)
546
#else
547
static Void_t* pfresize(vm, data, size, type, local)
548
Vmalloc_t* vm;
549
Void_t* data;
550
size_t size;
551
int type;
552
int local;
553
#endif
554
{
555
reg Pfobj_t *pf;
556
reg size_t s, news;
557
reg Void_t *addr;
558
reg char *file;
559
reg int line;
560
reg Void_t *func;
561
reg size_t oldsize;
562
reg Vmdata_t *vd = vm->data;
563
564
if(!data)
565
{ addr = pfalloc(vm, size, local);
566
if(addr && (type&VM_RSZERO) )
567
memset(addr, 0, size);
568
return addr;
569
}
570
if(size == 0)
571
{ (void)pffree(vm, data, local);
572
return NIL(Void_t*);
573
}
574
575
VMFLF(vm,file,line,func);
576
577
SETLOCK(vm, local);
578
579
/**/ASSERT(KPVADDR(vm,data,Vmbest->addrf) == 0 );
580
pf = PFOBJ(data);
581
s = oldsize = PFSIZE(data);
582
583
news = ROUND(size,ALIGN) + PF_EXTRA;
584
if((addr = KPVRESIZE(vm,data,news,(type&~VM_RSZERO),Vmbest->resizef)) )
585
{ if(pf)
586
{ PFFREE(pf) += (Vmulong_t)s;
587
PFNFREE(pf) += 1;
588
pf = PFREGION(pf);
589
PFFREE(pf) += (Vmulong_t)s;
590
PFNFREE(pf) += 1;
591
pfsetinfo(vm,(Vmuchar_t*)addr,size,file,line);
592
}
593
594
if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
595
{ vm->file = file; vm->line = line; vm->func = func;
596
(*_Vmtrace)(vm,(Vmuchar_t*)data,(Vmuchar_t*)addr,size,0);
597
}
598
}
599
else if(pf) /* reset old info */
600
{ PFALLOC(pf) -= (Vmulong_t)s;
601
PFNALLOC(pf) -= 1;
602
pf = PFREGION(pf);
603
PFALLOC(pf) -= (Vmulong_t)s;
604
PFNALLOC(pf) -= 1;
605
file = PFFILE(pf);
606
line = PFLINE(pf);
607
pfsetinfo(vm,(Vmuchar_t*)data,s,file,line);
608
}
609
610
if(addr && (type&VM_RSZERO) && oldsize < size)
611
{ reg Vmuchar_t *d = (Vmuchar_t*)addr+oldsize, *ed = (Vmuchar_t*)addr+size;
612
do { *d++ = 0; } while(d < ed);
613
}
614
615
CLRLOCK(vm, local);
616
617
return addr;
618
}
619
620
#if __STD_C
621
static long pfsize(Vmalloc_t* vm, Void_t* addr, int local)
622
#else
623
static long pfsize(vm, addr, local)
624
Vmalloc_t* vm;
625
Void_t* addr;
626
int local;
627
#endif
628
{
629
return (*Vmbest->addrf)(vm, addr, local) != 0 ? -1L : (long)PFSIZE(addr);
630
}
631
632
#if __STD_C
633
static long pfaddr(Vmalloc_t* vm, Void_t* addr, int local)
634
#else
635
static long pfaddr(vm, addr, local)
636
Vmalloc_t* vm;
637
Void_t* addr;
638
int local;
639
#endif
640
{
641
return (*Vmbest->addrf)(vm, addr, local);
642
}
643
644
#if __STD_C
645
static int pfcompact(Vmalloc_t* vm, int local)
646
#else
647
static int pfcompact(vm, local)
648
Vmalloc_t* vm;
649
int local;
650
#endif
651
{
652
return (*Vmbest->compactf)(vm, local);
653
}
654
655
#if __STD_C
656
static Void_t* pfalign(Vmalloc_t* vm, size_t size, size_t align, int local)
657
#else
658
static Void_t* pfalign(vm, size, align, local)
659
Vmalloc_t* vm;
660
size_t size;
661
size_t align;
662
int local;
663
#endif
664
{
665
reg size_t s;
666
reg Void_t *data;
667
reg char *file;
668
reg int line;
669
reg Void_t *func;
670
reg Vmdata_t *vd = vm->data;
671
672
VMFLF(vm,file,line,func);
673
674
SETLOCK(vm, local);
675
676
s = (size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN)) + PF_EXTRA;
677
if((data = KPVALIGN(vm,s,align,Vmbest->alignf)) )
678
{ pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
679
680
if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
681
{ vm->file = file; vm->line = line; vm->func = func;
682
(*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,align);
683
}
684
}
685
686
CLRLOCK(vm, local);
687
688
return data;
689
}
690
691
static Vmethod_t _Vmprofile =
692
{
693
pfalloc,
694
pfresize,
695
pffree,
696
pfaddr,
697
pfsize,
698
pfcompact,
699
pfalign,
700
VM_MTPROFILE
701
};
702
703
__DEFINE__(Vmethod_t*,Vmprofile,&_Vmprofile);
704
705
#ifdef NoF
706
NoF(vmprofile)
707
#endif
708
709
#endif
710
711