Annotation of researchv10no/cmd/lcc/c/profio.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.