1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)subr_mcount.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: /* last integrated from: gmon.c	4.10 (Berkeley) 1/14/83 */
  10: 
  11: #ifdef GPROF
  12: #include "gprof.h"
  13: #include "param.h"
  14: #include "systm.h"
  15: 
  16: /*
  17:  * Froms is actually a bunch of unsigned shorts indexing tos
  18:  */
  19: int profiling = 3;
  20: u_short *froms;
  21: struct tostruct *tos = 0;
  22: long tolimit = 0;
  23: #ifdef vax
  24: char    *s_lowpc = (char *)0x80000000;
  25: #endif
  26: extern char etext;
  27: char *s_highpc = &etext;
  28: u_long  s_textsize = 0;
  29: int ssiz;
  30: u_short *sbuf;
  31: u_short *kcount;
  32: 
  33: kmstartup()
  34: {
  35:     u_long  fromssize, tossize;
  36: 
  37:     /*
  38: 	 *	round lowpc and highpc to multiples of the density we're using
  39: 	 *	so the rest of the scaling (here and in gprof) stays in ints.
  40: 	 */
  41:     s_lowpc = (char *)
  42:         ROUNDDOWN((unsigned)s_lowpc, HISTFRACTION*sizeof(HISTCOUNTER));
  43:     s_highpc = (char *)
  44:         ROUNDUP((unsigned)s_highpc, HISTFRACTION*sizeof(HISTCOUNTER));
  45:     s_textsize = s_highpc - s_lowpc;
  46:     printf("Profiling kernel, s_textsize=%d [%x..%x]\n",
  47:         s_textsize, s_lowpc, s_highpc);
  48:     ssiz = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
  49:     sbuf = (u_short *)calloc(ssiz);
  50:     if (sbuf == 0) {
  51:         printf("No space for monitor buffer(s)\n");
  52:         return;
  53:     }
  54:     blkclr((caddr_t)sbuf, ssiz);
  55:     fromssize = s_textsize / HASHFRACTION;
  56:     froms = (u_short *)calloc(fromssize);
  57:     if (froms == 0) {
  58:         printf("No space for monitor buffer(s)\n");
  59:         cfreemem(sbuf, ssiz);
  60:         sbuf = 0;
  61:         return;
  62:     }
  63:     blkclr((caddr_t)froms, fromssize);
  64:     tolimit = s_textsize * ARCDENSITY / 100;
  65:     if (tolimit < MINARCS) {
  66:         tolimit = MINARCS;
  67:     } else if (tolimit > 65534) {
  68:         tolimit = 65534;
  69:     }
  70:     tossize = tolimit * sizeof(struct tostruct);
  71:     tos = (struct tostruct *)calloc(tossize);
  72:     if (tos == 0) {
  73:         printf("No space for monitor buffer(s)\n");
  74:         cfreemem(sbuf, ssiz);
  75:         sbuf = 0;
  76:         cfreemem(froms, fromssize);
  77:         froms = 0;
  78:         return;
  79:     }
  80:     blkclr((caddr_t)tos, tossize);
  81:     tos[0].link = 0;
  82:     ((struct phdr *)sbuf)->lpc = s_lowpc;
  83:     ((struct phdr *)sbuf)->hpc = s_highpc;
  84:     ((struct phdr *)sbuf)->ncnt = ssiz;
  85:     kcount = (u_short *)(((int)sbuf) + sizeof(struct phdr));
  86: #ifdef notdef
  87:     /*
  88: 	 *	profiling is what mcount checks to see if
  89: 	 *	all the data structures are ready!!!
  90: 	 */
  91:     profiling = 0;      /* patch by hand when you're ready */
  92: #endif
  93: }
  94: 
  95: #ifdef vax
  96: /*
  97:  * This routine is massaged so that it may be jsb'ed to
  98:  */
  99: asm(".text");
 100: asm("#the beginning of mcount()");
 101: asm(".data");
 102: mcount()
 103: {
 104:     register char           *selfpc;    /* r11 => r5 */
 105:     register unsigned short     *frompcindex;   /* r10 => r4 */
 106:     register struct tostruct    *top;       /* r9  => r3 */
 107:     register struct tostruct    *prevtop;   /* r8  => r2 */
 108:     register long           toindex;    /* r7  => r1 */
 109:     static int s;
 110: 
 111: #ifdef lint
 112:     selfpc = (char *)0;
 113:     frompcindex = 0;
 114: #else not lint
 115:     /*
 116: 	 *	find the return address for mcount,
 117: 	 *	and the return address for mcount's caller.
 118: 	 */
 119:     asm("	.text");      /* make sure we're in text space */
 120:     asm("	movl (sp), r11"); /* selfpc = ... (jsb frame) */
 121:     asm("	movl 16(fp), r10");   /* frompcindex =     (calls frame) */
 122: #endif not lint
 123:     /*
 124: 	 *	check that we are profiling
 125: 	 */
 126:     if (profiling) {
 127:         goto out;
 128:     }
 129:     /*
 130: 	 *	insure that we cannot be recursively invoked.
 131: 	 *	this requires that splhigh() and splx() below
 132: 	 *	do NOT call mcount!
 133: 	 */
 134:     s = splhigh();
 135:     /*
 136: 	 *	check that frompcindex is a reasonable pc value.
 137: 	 *	for example:	signal catchers get called from the stack,
 138: 	 *			not from text space.  too bad.
 139: 	 */
 140:     frompcindex = (unsigned short *)((long)frompcindex - (long)s_lowpc);
 141:     if ((unsigned long)frompcindex > s_textsize) {
 142:         goto done;
 143:     }
 144:     frompcindex =
 145:         &froms[((long)frompcindex) / (HASHFRACTION * sizeof(*froms))];
 146:     toindex = *frompcindex;
 147:     if (toindex == 0) {
 148:         /*
 149: 		 *	first time traversing this arc
 150: 		 */
 151:         toindex = ++tos[0].link;
 152:         if (toindex >= tolimit) {
 153:             goto overflow;
 154:         }
 155:         *frompcindex = toindex;
 156:         top = &tos[toindex];
 157:         top->selfpc = selfpc;
 158:         top->count = 1;
 159:         top->link = 0;
 160:         goto done;
 161:     }
 162:     top = &tos[toindex];
 163:     if (top->selfpc == selfpc) {
 164:         /*
 165: 		 *	arc at front of chain; usual case.
 166: 		 */
 167:         top->count++;
 168:         goto done;
 169:     }
 170:     /*
 171: 	 *	have to go looking down chain for it.
 172: 	 *	top points to what we are looking at,
 173: 	 *	prevtop points to previous top.
 174: 	 *	we know it is not at the head of the chain.
 175: 	 */
 176:     for (; /* goto done */; ) {
 177:         if (top->link == 0) {
 178:             /*
 179: 			 *	top is end of the chain and none of the chain
 180: 			 *	had top->selfpc == selfpc.
 181: 			 *	so we allocate a new tostruct
 182: 			 *	and link it to the head of the chain.
 183: 			 */
 184:             toindex = ++tos[0].link;
 185:             if (toindex >= tolimit) {
 186:                 goto overflow;
 187:             }
 188:             top = &tos[toindex];
 189:             top->selfpc = selfpc;
 190:             top->count = 1;
 191:             top->link = *frompcindex;
 192:             *frompcindex = toindex;
 193:             goto done;
 194:         }
 195:         /*
 196: 		 *	otherwise, check the next arc on the chain.
 197: 		 */
 198:         prevtop = top;
 199:         top = &tos[top->link];
 200:         if (top->selfpc == selfpc) {
 201:             /*
 202: 			 *	there it is.
 203: 			 *	increment its count
 204: 			 *	move it to the head of the chain.
 205: 			 */
 206:             top->count++;
 207:             toindex = prevtop->link;
 208:             prevtop->link = top->link;
 209:             top->link = *frompcindex;
 210:             *frompcindex = toindex;
 211:             goto done;
 212:         }
 213: 
 214:     }
 215: done:
 216:     splx(s);
 217:     /* and fall through */
 218: out:
 219:     asm("	rsb");
 220: 
 221: overflow:
 222:     profiling = 3;
 223:     printf("mcount: tos overflow\n");
 224:     goto out;
 225: }
 226: asm(".text");
 227: asm("#the end of mcount()");
 228: asm(".data");
 229: #endif vax
 230: #endif GPROF

Defined functions

kmstartup defined in line 33; used 1 times
mcount defined in line 102; never used

Defined variables

froms defined in line 20; used 7 times
kcount defined in line 31; used 1 times
  • in line 85
profiling defined in line 19; used 4 times
s_highpc defined in line 27; used 5 times
s_lowpc defined in line 24; used 7 times
s_textsize defined in line 28; used 6 times
sbuf defined in line 30; used 11 times
ssiz defined in line 29; used 6 times
tolimit defined in line 22; used 8 times
tos defined in line 21; used 10 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1232
Valid CSS Valid XHTML 1.0 Strict