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