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
Defined variables
froms
defined in line
20; used 7 times
sbuf
defined in line
30; used 11 times
ssiz
defined in line
29; used 6 times
tos
defined in line
21; used 10 times