|
|
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.