|
|
1.1 root 1: /* C compiler: prof.out input
2: *
3: * prof.out format:
4: * #files
5: * name
6: * ... (#files-1 times)
7: * #functions
8: * name file# x y count caller file x y
9: * ... (#functions-1 times)
10: * #points
11: * file# x y count
12: * ... (#points-1 times)
13: */
14:
15: struct file { /* per-file prof.out data: */
16: struct file *link; /* link to next file */
17: char *name; /* file name */
18: int size; /* size of counts[] */
19: int count; /* counts[0..count-1] hold valid data */
20: struct count { /* count data: */
21: int x, y; /* source coordinate */
22: int count; /* associated execution count */
23: } *counts;
24: struct func { /* function data: */
25: struct func *link; /* link to next function */
26: char *name; /* function name */
27: struct count count; /* total number of calls */
28: struct caller { /* caller data: */
29: struct caller *link; /* link to next caller */
30: char *name; /* caller's name */
31: char *file; /* call site: file, x, y */
32: int x, y;
33: int count; /* number of calls from this site */
34: } *callers;
35: } *funcs; /* list of functions */
36: } *filelist;
37:
38: #ifdef BPRINT
39: #define MAXTOKEN 64
40: #define dclproto(func,args) func args
41: #define ngetc() getc(fp)
42: static FILE *fp;
43: #else
44: #include "c.h"
45: #define EOF -1
46: #define ngetc() (*cp == 0 ? EOF : *cp == '\n' ? (cp++, nextline(), '\n') : *cp++)
47: dclproto(extern void qsort,(struct count *, int, int, int (*)(const void *, const void *)));
48: #endif
49:
50: dclproto(static void acaller,(char *, char *, int, int, int, struct func *));
51: dclproto(static int compare,(struct count *, struct count *));
52: dclproto(static struct func *afunction,(char *, char *, int, int, int));
53: dclproto(static void apoint,(int, char *, int, int, int));
54: dclproto(static struct file *findfile,(char *));
55: dclproto(static int gather,(void));
56: dclproto(static int getd,(void));
57: dclproto(static char *getstr,(void));
58:
59: /* acaller - add caller and site (file,x,y) to callee's callers list */
60: static void acaller(caller, file, x, y, count, callee) char *caller, *file; struct func *callee; {
61: struct caller *q;
62:
63: assert(callee);
64: for (q = callee->callers; q && (caller != q->name
65: || file != q->file || x != q->x || y != q->y); q = q->link)
66: ;
67: if (!q) {
68: struct caller **r;
69: q = (struct caller *)alloc(sizeof *q);
70: q->name = caller;
71: q->file = file;
72: q->x = x;
73: q->y = y;
74: q->count = 0;
75: for (r = &callee->callers; *r && (strcmp(q->name, (*r)->name) > 0
76: || strcmp(q->file, (*r)->file) > 0 || q->y > (*r)->y || q->y > (*r)->y); r = &(*r)->link)
77: ;
78: q->link = *r;
79: *r = q;
80: }
81: q->count += count;
82: }
83:
84: /* afunction - add function name and its data to file's function list */
85: static struct func *afunction(name, file, x, y, count) char *name, *file; {
86: struct file *p = findfile(file);
87: struct func *q;
88:
89: assert(p);
90: for (q = p->funcs; q && name != q->name; q = q->link)
91: ;
92: if (!q) {
93: struct func **r;
94: q = (struct func *)alloc(sizeof *q);
95: q->name = name;
96: q->count.x = x;
97: q->count.y = y;
98: q->count.count = 0;
99: q->callers = 0;
100: for (r = &p->funcs; *r && compare(&q->count, &(*r)->count) > 0; r = &(*r)->link)
101: ;
102: q->link = *r;
103: *r = q;
104: }
105: q->count.count += count;
106: return q;
107: }
108:
109: /* apoint - append execution point i to file's data */
110: static void apoint(i, file, x, y, count) char *file; {
111: struct file *p = findfile(file);
112:
113: assert(p);
114: if (i >= p->size) {
115: int j;
116: if (p->size == 0) {
117: p->size = i >= 200 ? 2*i : 200;
118: p->counts = (struct count *)alloc(p->size*sizeof(struct count));
119: } else {
120: struct count *new;
121: p->size = 2*i;
122: new = (struct count *)alloc(p->size*sizeof(struct count));
123: for (j = 0; j < p->count; j++)
124: new[j] = p->counts[j];
125: p->counts = new;
126: }
127: for (j = p->count; j < p->size; j++) {
128: static struct count z;
129: p->counts[j] = z;
130: }
131: }
132: p->counts[i].x = x;
133: p->counts[i].y = y;
134: p->counts[i].count += count;
135: if (i >= p->count)
136: p->count = i + 1;
137: }
138:
139: /* compare - return <0, 0, >0 if a<b, a==b, a>b, resp. */
140: static int compare(a, b) struct count *a, *b; {
141: if (a->y == b->y)
142: return a->x - b->x;
143: return a->y - b->y;
144: }
145:
146: /* findcount - return count associated with (file,x,y) or -1 */
147: int findcount(file, x, y) char *file; {
148: static struct file *cursor;
149:
150: if (cursor == 0 || cursor->name != file)
151: cursor = findfile(file);
152: if (cursor) {
153: int l, u;
154: struct count *c = cursor->counts;
155: for (l = 0, u = cursor->count - 1; l <= u; ) {
156: int k = (l + u)/2;
157: if (c[k].y > y || c[k].y == y && c[k].x > x)
158: u = k - 1;
159: else if (c[k].y < y || c[k].y == y && c[k].x < x)
160: l = k + 1;
161: else
162: return c[k].count;
163: }
164: }
165: return -1;
166: }
167:
168: /* findfile - return file name's file list entry, or 0 */
169: static struct file *findfile(name) char *name; {
170: struct file *p;
171:
172: for (p = filelist; p; p = p->link)
173: if (p->name == name)
174: return p;
175: return 0;
176: }
177:
178: /* findfunc - return count associated with function name in file or -1 */
179: int findfunc(name, file) char *name, *file; {
180: static struct file *cursor;
181:
182: if (cursor == 0 || cursor->name != file)
183: cursor = findfile(file);
184: if (cursor) {
185: struct func *p;
186: for (p = cursor->funcs; p; p = p->link)
187: if (p->name == name)
188: return p->count.count;
189: }
190: return -1;
191: }
192:
193: /* gather - read prof.out data from fd */
194: static int gather() {
195: int i, nfiles, nfuncs, npoints;
196: char *files[64];
197:
198: if ((nfiles = getd()) < 0)
199: return 0;
200: assert(nfiles < sizeof files/sizeof files[0]);
201: for (i = 0; i < nfiles; i++) {
202: if ((files[i] = getstr()) == 0)
203: return -1;
204: if (!findfile(files[i])) {
205: struct file *new = (struct file *)alloc(sizeof *new);
206: new->name = files[i];
207: new->size = new->count = 0;
208: new->counts = 0;
209: new->funcs = 0;
210: new->link = filelist;
211: filelist = new;
212: }
213: }
214: if ((nfuncs = getd()) < 0)
215: return -1;
216: for (i = 0; i < nfuncs; i++) {
217: struct func *q;
218: char *name, *file;
219: int f, x, y, count;
220: if ((name = getstr()) == 0 || (f = getd()) <= 0
221: || (x = getd()) < 0 || (y = getd()) < 0 || (count = getd()) < 0)
222: return -1;
223: q = afunction(name, files[f-1], x, y, count);
224: if ((name = getstr()) == 0 || (file = getstr()) == 0
225: || (x = getd()) < 0 || (y = getd()) < 0)
226: return -1;
227: if (*name != '?')
228: acaller(name, file, x, y, count, q);
229: }
230: if ((npoints = getd()) < 0)
231: return -1;
232: for (i = 0; i < npoints; i++) {
233: int f, x, y, count;
234: if ((f = getd()) < 0 || (x = getd()) < 0 || (y = getd()) < 0
235: || (count = getd()) < 0)
236: return -1;
237: if (f)
238: apoint(i, files[f-1], x, y, count);
239: }
240: return 1;
241: }
242:
243: /* getd - read a non-negative number */
244: static int getd() {
245: int c, n = 0;
246:
247: while ((c = ngetc()) != EOF && (c == ' ' || c == '\n' || c == '\t'))
248: ;
249: if (c >= '0' && c <= '9') {
250: do
251: n = 10*n + (c - '0');
252: while ((c = ngetc()) >= '0' && c <= '9');
253: return n;
254: }
255: return -1;
256: }
257:
258: /* getstr - read a string */
259: static char *getstr() {
260: int c;
261: char buf[MAXTOKEN], *s = buf;
262:
263: while ((c = ngetc()) != EOF && c != ' ' && c != '\n' && c != '\t')
264: if (s - buf < sizeof buf - 2)
265: *s++ = c;
266: *s = 0;
267: return s == buf ? (char *)0 : string(buf);
268: }
269:
270: /* process - read prof.out data from file */
271: int process(file) char *file; {
272: int more;
273:
274: #ifdef BPRINT
275: if ((fp = fopen(file, "r"))) {
276: while ((more = gather()) > 0)
277: ;
278: fclose(fp);
279: return more < 0 ? more : 1;
280: }
281: #else
282: int fd;
283: struct file *p;
284:
285: if ((fd = open(file, 0)) >= 0) {
286: inputInit(fd);
287: while ((more = gather()) > 0)
288: ;
289: close(fd);
290: if (more < 0)
291: return more;
292: for (p = filelist; p; p = p->link)
293: qsort(p->counts, p->count, sizeof *p->counts,
294: (dclproto(int (*),(const void *, const void *)))
295: compare);
296:
297: return 1;
298: }
299: #endif
300: return 0;
301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.