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