xref: /inferno-os/libinterp/heapaudit.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "interp.h"
3*37da2899SCharles.Forsyth #include "pool.h"
4*37da2899SCharles.Forsyth 
5*37da2899SCharles.Forsyth 
6*37da2899SCharles.Forsyth typedef struct Audit Audit;
7*37da2899SCharles.Forsyth struct Audit
8*37da2899SCharles.Forsyth {
9*37da2899SCharles.Forsyth 	Type*	t;
10*37da2899SCharles.Forsyth 	ulong	n;
11*37da2899SCharles.Forsyth 	ulong	size;
12*37da2899SCharles.Forsyth 	Audit*	hash;
13*37da2899SCharles.Forsyth };
14*37da2899SCharles.Forsyth Audit*	ahash[128];
15*37da2899SCharles.Forsyth extern	Pool*	heapmem;
16*37da2899SCharles.Forsyth extern void conslog(char*, ...);
17*37da2899SCharles.Forsyth #define	conslog	print
18*37da2899SCharles.Forsyth 
19*37da2899SCharles.Forsyth typedef struct Typed	Typed;
20*37da2899SCharles.Forsyth typedef struct Ptyped	Ptyped;
21*37da2899SCharles.Forsyth 
22*37da2899SCharles.Forsyth extern Type Trdchan;
23*37da2899SCharles.Forsyth extern Type Twrchan;
24*37da2899SCharles.Forsyth 
25*37da2899SCharles.Forsyth struct Typed
26*37da2899SCharles.Forsyth {
27*37da2899SCharles.Forsyth 	char*	name;
28*37da2899SCharles.Forsyth 	Type*	ptr;
29*37da2899SCharles.Forsyth } types[] =
30*37da2899SCharles.Forsyth {
31*37da2899SCharles.Forsyth 	{"array",	&Tarray},
32*37da2899SCharles.Forsyth 	{"byte",	&Tbyte},
33*37da2899SCharles.Forsyth 	{"channel",	&Tchannel},
34*37da2899SCharles.Forsyth 	{"list",	&Tlist},
35*37da2899SCharles.Forsyth 	{"modlink",	&Tmodlink},
36*37da2899SCharles.Forsyth 	{"ptr",		&Tptr},
37*37da2899SCharles.Forsyth 	{"string",	&Tstring},
38*37da2899SCharles.Forsyth 
39*37da2899SCharles.Forsyth 	{"rdchan",	&Trdchan},
40*37da2899SCharles.Forsyth 	{"wrchan",	&Twrchan},
41*37da2899SCharles.Forsyth 	{"unspec",	nil},
42*37da2899SCharles.Forsyth 
43*37da2899SCharles.Forsyth 	0
44*37da2899SCharles.Forsyth };
45*37da2899SCharles.Forsyth 
46*37da2899SCharles.Forsyth extern Type* TDisplay;
47*37da2899SCharles.Forsyth extern Type* TFont;
48*37da2899SCharles.Forsyth extern Type* TImage;
49*37da2899SCharles.Forsyth extern Type* TScreen;
50*37da2899SCharles.Forsyth extern Type* TFD;
51*37da2899SCharles.Forsyth extern Type* TFileIO;
52*37da2899SCharles.Forsyth extern Type* Tread;
53*37da2899SCharles.Forsyth extern Type* Twrite;
54*37da2899SCharles.Forsyth extern Type* fakeTkTop;
55*37da2899SCharles.Forsyth 
56*37da2899SCharles.Forsyth extern Type* TSigAlg;
57*37da2899SCharles.Forsyth extern Type* TCertificate;
58*37da2899SCharles.Forsyth extern Type* TSK;
59*37da2899SCharles.Forsyth extern Type* TPK;
60*37da2899SCharles.Forsyth extern Type* TDigestState;
61*37da2899SCharles.Forsyth extern Type* TAuthinfo;
62*37da2899SCharles.Forsyth extern Type* TDESstate;
63*37da2899SCharles.Forsyth extern Type* TIPint;
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth struct Ptyped
66*37da2899SCharles.Forsyth {
67*37da2899SCharles.Forsyth 	char*	name;
68*37da2899SCharles.Forsyth 	Type**	ptr;
69*37da2899SCharles.Forsyth } ptypes[] =
70*37da2899SCharles.Forsyth {
71*37da2899SCharles.Forsyth 	{"Display",	&TDisplay},
72*37da2899SCharles.Forsyth 	{"Font",	&TFont},
73*37da2899SCharles.Forsyth 	{"Image",	&TImage},
74*37da2899SCharles.Forsyth 	{"Screen",	&TScreen},
75*37da2899SCharles.Forsyth 
76*37da2899SCharles.Forsyth 	{"SigAlg",	&TSigAlg},
77*37da2899SCharles.Forsyth 	{"Certificate",	&TCertificate},
78*37da2899SCharles.Forsyth 	{"SK",		&TSK},
79*37da2899SCharles.Forsyth 	{"PK",		&TPK},
80*37da2899SCharles.Forsyth 	{"DigestState",	&TDigestState},
81*37da2899SCharles.Forsyth 	{"Authinfo",	&TAuthinfo},
82*37da2899SCharles.Forsyth 	{"DESstate",	&TDESstate},
83*37da2899SCharles.Forsyth 	{"IPint",	&TIPint},
84*37da2899SCharles.Forsyth 
85*37da2899SCharles.Forsyth 	{"FD",		&TFD},
86*37da2899SCharles.Forsyth 	{"FileIO",	&TFileIO},
87*37da2899SCharles.Forsyth 
88*37da2899SCharles.Forsyth /*	{"Fioread",	&Tread},	*/
89*37da2899SCharles.Forsyth /*	{"Fiowrite",	&Twrite},	*/
90*37da2899SCharles.Forsyth 
91*37da2899SCharles.Forsyth 	{"TkTop",	&fakeTkTop},
92*37da2899SCharles.Forsyth 
93*37da2899SCharles.Forsyth 	0
94*37da2899SCharles.Forsyth };
95*37da2899SCharles.Forsyth 
96*37da2899SCharles.Forsyth static Audit **
auditentry(Type * t)97*37da2899SCharles.Forsyth auditentry(Type *t)
98*37da2899SCharles.Forsyth {
99*37da2899SCharles.Forsyth 	Audit **h, *a;
100*37da2899SCharles.Forsyth 
101*37da2899SCharles.Forsyth 	for(h = &ahash[((ulong)t>>2)%nelem(ahash)]; (a = *h) != nil; h = &a->hash)
102*37da2899SCharles.Forsyth 		if(a->t == t)
103*37da2899SCharles.Forsyth 			break;
104*37da2899SCharles.Forsyth 	return h;
105*37da2899SCharles.Forsyth }
106*37da2899SCharles.Forsyth 
107*37da2899SCharles.Forsyth void
heapaudit(void)108*37da2899SCharles.Forsyth heapaudit(void)
109*37da2899SCharles.Forsyth {
110*37da2899SCharles.Forsyth 	Type *t;
111*37da2899SCharles.Forsyth 	Heap *h;
112*37da2899SCharles.Forsyth 	List *l;
113*37da2899SCharles.Forsyth 	Array *r;
114*37da2899SCharles.Forsyth 	Module *m;
115*37da2899SCharles.Forsyth 	int i, ntype, n;
116*37da2899SCharles.Forsyth 	Bhdr *b, *base, *limit;
117*37da2899SCharles.Forsyth 	Audit *a, **hash;
118*37da2899SCharles.Forsyth 
119*37da2899SCharles.Forsyth 	acquire();
120*37da2899SCharles.Forsyth 
121*37da2899SCharles.Forsyth 	b = poolchain(heapmem);
122*37da2899SCharles.Forsyth 	base = b;
123*37da2899SCharles.Forsyth 	limit = B2LIMIT(b);
124*37da2899SCharles.Forsyth 
125*37da2899SCharles.Forsyth 	while(b != nil) {
126*37da2899SCharles.Forsyth 		if(b->magic == MAGIC_A) {
127*37da2899SCharles.Forsyth 			h = B2D(b);
128*37da2899SCharles.Forsyth 			t = h->t;
129*37da2899SCharles.Forsyth 			n = 1;
130*37da2899SCharles.Forsyth 			if(t == &Tlist) {
131*37da2899SCharles.Forsyth 				l = H2D(List*, h);
132*37da2899SCharles.Forsyth 				t = l->t;
133*37da2899SCharles.Forsyth 			} else if(t == &Tarray) {
134*37da2899SCharles.Forsyth 				r = H2D(Array*, h);
135*37da2899SCharles.Forsyth 				t = r->t;
136*37da2899SCharles.Forsyth 				n = r->len;
137*37da2899SCharles.Forsyth 			}
138*37da2899SCharles.Forsyth 			hash = auditentry(t);
139*37da2899SCharles.Forsyth 			if((a = *hash) == nil){
140*37da2899SCharles.Forsyth 				a = malloc(sizeof(Audit));
141*37da2899SCharles.Forsyth 				if(a == nil)
142*37da2899SCharles.Forsyth 					continue;
143*37da2899SCharles.Forsyth 				a->n = 1;
144*37da2899SCharles.Forsyth 				a->t = t;
145*37da2899SCharles.Forsyth 				a->hash = *hash;
146*37da2899SCharles.Forsyth 				*hash = a;
147*37da2899SCharles.Forsyth 			}else
148*37da2899SCharles.Forsyth 				a->n++;
149*37da2899SCharles.Forsyth 			if(t != nil && t != &Tmodlink && t != &Tstring)
150*37da2899SCharles.Forsyth 				a->size += t->size*n;
151*37da2899SCharles.Forsyth 			else
152*37da2899SCharles.Forsyth 				a->size += b->size;
153*37da2899SCharles.Forsyth 		}
154*37da2899SCharles.Forsyth 		b = B2NB(b);
155*37da2899SCharles.Forsyth 		if(b >= limit) {
156*37da2899SCharles.Forsyth 			base = base->clink;
157*37da2899SCharles.Forsyth 			if(base == nil)
158*37da2899SCharles.Forsyth 				break;
159*37da2899SCharles.Forsyth 			b = base;
160*37da2899SCharles.Forsyth 			limit = B2LIMIT(base);
161*37da2899SCharles.Forsyth 		}
162*37da2899SCharles.Forsyth 	}
163*37da2899SCharles.Forsyth 
164*37da2899SCharles.Forsyth 	for(m = modules; m != nil; m = m->link) {
165*37da2899SCharles.Forsyth 		for(i = 0; i < m->ntype; i++)
166*37da2899SCharles.Forsyth 			if((a = *auditentry(m->type[i])) != nil) {
167*37da2899SCharles.Forsyth 				conslog("%8ld %8lud %3d %s\n", a->n, a->size, i, m->path);
168*37da2899SCharles.Forsyth 				a->size = 0;
169*37da2899SCharles.Forsyth 				break;
170*37da2899SCharles.Forsyth 			}
171*37da2899SCharles.Forsyth 	}
172*37da2899SCharles.Forsyth 
173*37da2899SCharles.Forsyth 	for(i = 0; (t = types[i].ptr) != nil; i++)
174*37da2899SCharles.Forsyth 		if((a = *auditentry(t)) != nil){
175*37da2899SCharles.Forsyth 			conslog("%8ld %8lud %s\n", a->n, a->size, types[i].name);
176*37da2899SCharles.Forsyth 			a->size = 0;
177*37da2899SCharles.Forsyth 			break;
178*37da2899SCharles.Forsyth 		}
179*37da2899SCharles.Forsyth 
180*37da2899SCharles.Forsyth 	for(i = 0; ptypes[i].name != nil; i++)
181*37da2899SCharles.Forsyth 		if((a = *auditentry(*ptypes[i].ptr)) != nil){
182*37da2899SCharles.Forsyth 			conslog("%8ld %8lud %s\n", a->n, a->size, ptypes[i].name);
183*37da2899SCharles.Forsyth 			a->size = 0;
184*37da2899SCharles.Forsyth 			break;
185*37da2899SCharles.Forsyth 		}
186*37da2899SCharles.Forsyth 
187*37da2899SCharles.Forsyth 	ntype = 0;
188*37da2899SCharles.Forsyth 	for(i = 0; i < nelem(ahash); i++)
189*37da2899SCharles.Forsyth 		while((a = ahash[i]) != nil){
190*37da2899SCharles.Forsyth 			ahash[i] = a->hash;
191*37da2899SCharles.Forsyth 			if(a->size != 0)
192*37da2899SCharles.Forsyth 				conslog("%8ld %8lud %p\n", a->n, a->size, a->t);
193*37da2899SCharles.Forsyth 			free(a);
194*37da2899SCharles.Forsyth 			ntype++;
195*37da2899SCharles.Forsyth 		}
196*37da2899SCharles.Forsyth 
197*37da2899SCharles.Forsyth 	release();
198*37da2899SCharles.Forsyth }
199