Annotation of researchv10no/cmd/lcc/c/profio.c, revision 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.