Print this page
libconv
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/gprof/common/printgprof.c
+++ new/usr/src/cmd/sgs/gprof/common/printgprof.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 + *
26 + * Copyright 2018 Jason King
25 27 */
26 28
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 29 #include <ctype.h>
30 30 #include <string.h>
31 31 #include <sys/param.h>
32 32 #include <stdlib.h>
33 33 #include "conv.h"
34 34 #include "gprof.h"
35 35
36 36 void print_demangled_name(int, nltype *);
37 37 void striped_name(char *, nltype **);
38 38
39 39 extern long hz;
40 40
41 41 /*
42 42 * Symbols that must never be printed, no matter what.
43 43 */
44 44 char *splsym[] = {
45 45 PRF_ETEXT,
46 46 PRF_EXTSYM,
47 47 PRF_MEMTERM,
48 48 NULL
49 49 };
50 50
51 51 static bool is_special_sym(nltype *nlp);
52 52
53 53 const char *
54 54 demangled_name(nltype *selfp)
55 55 {
56 56 if (!Cflag)
57 57 return (selfp->name);
58 58
59 59 return (conv_demangle_name(selfp->name));
60 60 }
61 61
62 62 void
63 63 printprof(void)
64 64 {
65 65 nltype *np;
66 66 nltype **sortednlp;
67 67 int i, index;
68 68 int print_count = number_funcs_toprint;
69 69 bool print_flag = TRUE;
70 70 mod_info_t *mi;
71 71
72 72 actime = 0.0;
73 73 (void) printf("\f\n");
74 74 flatprofheader();
75 75
76 76 /*
77 77 * Sort the symbol table in by time
78 78 */
79 79 sortednlp = (nltype **) calloc(total_names, sizeof (nltype *));
80 80 if (sortednlp == (nltype **) 0) {
81 81 (void) fprintf(stderr,
82 82 "[printprof] ran out of memory for time sorting\n");
83 83 }
84 84
85 85 index = 0;
86 86 for (mi = &modules; mi; mi = mi->next) {
87 87 for (i = 0; i < mi->nname; i++)
88 88 sortednlp[index++] = &(mi->nl[i]);
89 89 }
90 90
91 91 qsort(sortednlp, total_names, sizeof (nltype *), timecmp);
92 92
93 93 for (index = 0; (index < total_names) && print_flag; index += 1) {
94 94 np = sortednlp[index];
95 95 flatprofline(np);
96 96 if (nflag) {
97 97 if (--print_count == 0)
98 98 print_flag = FALSE;
99 99 }
100 100 }
101 101 actime = 0.0;
102 102 free(sortednlp);
103 103 }
104 104
105 105 int
106 106 timecmp(const void *arg1, const void *arg2)
107 107 {
108 108 nltype **npp1 = (nltype **)arg1;
109 109 nltype **npp2 = (nltype **)arg2;
110 110 double timediff;
111 111 long calldiff;
112 112
113 113 timediff = (*npp2)->time - (*npp1)->time;
114 114
115 115 if (timediff > 0.0)
116 116 return (1);
117 117
118 118 if (timediff < 0.0)
119 119 return (-1);
120 120
121 121 calldiff = (*npp2)->ncall - (*npp1)->ncall;
122 122
123 123 if (calldiff > 0)
124 124 return (1);
125 125
126 126 if (calldiff < 0)
127 127 return (-1);
128 128
129 129 return (strcmp((*npp1)->name, (*npp2)->name));
130 130 }
131 131
132 132 /*
133 133 * header for flatprofline
134 134 */
135 135 void
136 136 flatprofheader()
137 137 {
138 138
139 139 if (bflag)
140 140 printblurb(FLAT_BLURB);
141 141
142 142 if (old_style) {
143 143 (void) printf(
144 144 "\ngranularity: each sample hit covers %d byte(s)",
145 145 (long)scale * sizeof (UNIT));
146 146 if (totime > 0.0) {
147 147 (void) printf(" for %.2f%% of %.2f seconds\n\n",
148 148 100.0/totime, totime / hz);
149 149 } else {
150 150 (void) printf(" no time accumulated\n\n");
151 151 /*
152 152 * this doesn't hurt since all the numerators will
153 153 * be zero.
154 154 */
155 155 totime = 1.0;
156 156 }
157 157 }
158 158
159 159 (void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
160 160 "% ", "cumulative", "self ", "", "self ", "total ", "");
161 161 (void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
162 162 "time", "seconds ", "seconds", "calls",
163 163 "ms/call", "ms/call", "name");
164 164 }
165 165
166 166 void
167 167 flatprofline(nltype *np)
168 168 {
169 169 if (zflag == 0 && np->ncall == 0 && np->time == 0)
170 170 return;
171 171
172 172 /*
173 173 * Do not print certain special symbols, like PRF_EXTSYM, etc.
174 174 * even if zflag was on.
175 175 */
176 176 if (is_special_sym(np))
177 177 return;
178 178
179 179 actime += np->time;
180 180
181 181 (void) printf("%5.1f %10.2f %8.2f",
182 182 100 * np->time / totime, actime / hz, np->time / hz);
183 183
184 184 if (np->ncall != 0) {
185 185 (void) printf(" %8lld %8.2f %8.2f ", np->ncall,
186 186 1000 * np->time / hz / np->ncall,
187 187 1000 * (np->time + np->childtime) / hz / np->ncall);
188 188 } else {
189 189 if (!Cflag)
190 190 (void) printf(" %8.8s %8.8s %8.8s ", "", "", "");
191 191 else
192 192 (void) printf(" %8.8s %8.8s %8.8s ", "", "", "");
193 193 }
194 194
195 195 printname(np);
196 196
197 197 if (Cflag)
198 198 print_demangled_name(55, np);
199 199
200 200 (void) printf("\n");
201 201 }
202 202
203 203 void
204 204 gprofheader()
205 205 {
206 206
207 207 if (bflag)
208 208 printblurb(CALLG_BLURB);
209 209
210 210 if (old_style) {
211 211
212 212 (void) printf(
213 213 "\ngranularity: each sample hit covers %d byte(s)",
214 214 (long)scale * sizeof (UNIT));
215 215
216 216 if (printtime > 0.0) {
217 217 (void) printf(" for %.2f%% of %.2f seconds\n\n",
218 218 100.0/printtime, printtime / hz);
219 219 } else {
220 220 (void) printf(" no time propagated\n\n");
221 221 /*
222 222 * this doesn't hurt, since all the numerators
223 223 * will be 0.0
224 224 */
225 225 printtime = 1.0;
226 226 }
227 227 } else {
228 228 (void) printf(
229 229 "\ngranularity: each pc-hit is considered 1 tick");
230 230 if (hz != 1) {
231 231 (void) printf(" (@ %4.3f seconds per tick)",
232 232 (double)1.0 / hz);
233 233 }
234 234 (void) puts("\n\n");
235 235 }
236 236
237 237 (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
238 238 "", "", "", "", "called", "total", "parents");
239 239 (void) printf("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
240 240 "index", "%time", "self", "descendents",
241 241 "called", "self", "name", "index");
242 242 (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
243 243 "", "", "", "", "called", "total", "children");
244 244 (void) printf("\n");
245 245 }
246 246
247 247 void
248 248 gprofline(nltype *np)
249 249 {
250 250 char kirkbuffer[BUFSIZ];
251 251
252 252 (void) sprintf(kirkbuffer, "[%d]", np->index);
253 253 (void) printf("%-6.6s %5.1f %7.2f %11.2f", kirkbuffer,
254 254 100 * (np->propself + np->propchild) / printtime,
255 255 np->propself / hz, np->propchild / hz);
256 256
257 257 if ((np->ncall + np->selfcalls) != 0) {
258 258 (void) printf(" %7lld", np->ncall);
259 259
260 260 if (np->selfcalls != 0)
261 261 (void) printf("+%-7lld ", np->selfcalls);
262 262 else
263 263 (void) printf(" %7.7s ", "");
264 264 } else {
265 265 (void) printf(" %7.7s %7.7s ", "", "");
266 266 }
267 267
268 268 printname(np);
269 269
270 270 if (Cflag)
271 271 print_demangled_name(50, np);
272 272
273 273 (void) printf("\n");
274 274 }
275 275
276 276 static bool
277 277 is_special_sym(nltype *nlp)
278 278 {
279 279 int i;
280 280
281 281 if (nlp->name == NULL)
282 282 return (FALSE);
283 283
284 284 for (i = 0; splsym[i]; i++)
285 285 if (strcmp(splsym[i], nlp->name) == 0)
286 286 return (TRUE);
287 287
288 288 return (FALSE);
289 289 }
290 290
291 291 void
292 292 printgprof(nltype **timesortnlp)
293 293 {
294 294 int index;
295 295 nltype *parentp;
296 296 int print_count = number_funcs_toprint;
297 297 bool count_flag = TRUE;
298 298
299 299 /*
300 300 * Print out the structured profiling list
301 301 */
302 302 gprofheader();
303 303
304 304 for (index = 0; index < total_names + ncycle && count_flag; index++) {
305 305 parentp = timesortnlp[index];
306 306 if (zflag == 0 && parentp->ncall == 0 &&
307 307 parentp->selfcalls == 0 && parentp->propself == 0 &&
308 308 parentp -> propchild == 0)
309 309 continue;
310 310
311 311 if (!parentp->printflag)
312 312 continue;
313 313
314 314 /*
315 315 * Do not print certain special symbols, like PRF_EXTSYM, etc.
316 316 * even if zflag was on.
317 317 */
318 318 if (is_special_sym(parentp))
319 319 continue;
320 320
321 321 if (parentp->name == 0 && parentp->cycleno != 0) {
322 322 /*
323 323 * cycle header
324 324 */
325 325 printcycle(parentp);
326 326 printmembers(parentp);
327 327 } else {
328 328 printparents(parentp);
329 329 gprofline(parentp);
330 330 printchildren(parentp);
331 331 }
332 332
333 333 (void) printf("\n");
334 334 (void) printf(
335 335 "-----------------------------------------------\n");
336 336 (void) printf("\n");
337 337
338 338 if (nflag) {
339 339 --print_count;
340 340 if (print_count == 0)
341 341 count_flag = FALSE;
342 342 }
343 343 }
344 344 free(timesortnlp);
345 345 }
346 346
347 347 /*
348 348 * sort by decreasing propagated time
349 349 * if times are equal, but one is a cycle header,
350 350 * say that's first (e.g. less, i.e. -1).
351 351 * if one's name doesn't have an underscore and the other does,
352 352 * say the one is first.
353 353 * all else being equal, sort by names.
354 354 */
355 355 int
356 356 totalcmp(const void *arg1, const void *arg2)
357 357 {
358 358 nltype **npp1 = (nltype **)arg1;
359 359 nltype **npp2 = (nltype **)arg2;
360 360 nltype *np1 = *npp1;
361 361 nltype *np2 = *npp2;
362 362 double diff;
363 363
364 364 diff = (np1->propself + np1->propchild) -
365 365 (np2->propself + np2->propchild);
366 366
367 367 if (diff < 0.0)
368 368 return (1);
369 369 if (diff > 0.0)
370 370 return (-1);
371 371 if (np1->name == 0 && np1->cycleno != 0)
372 372 return (-1);
373 373 if (np2->name == 0 && np2->cycleno != 0)
374 374 return (1);
375 375 if (np1->name == 0)
376 376 return (-1);
377 377 if (np2->name == 0)
378 378 return (1);
379 379
380 380 if (*(np1->name) != '_' && *(np2->name) == '_')
381 381 return (-1);
382 382 if (*(np1->name) == '_' && *(np2->name) != '_')
383 383 return (1);
384 384 if (np1->ncall > np2->ncall)
385 385 return (-1);
386 386 if (np1->ncall < np2->ncall)
387 387 return (1);
388 388 return (strcmp(np1->name, np2->name));
389 389 }
390 390
391 391 void
392 392 printparents(nltype *childp)
393 393 {
394 394 nltype *parentp;
395 395 arctype *arcp;
396 396 nltype *cycleheadp;
397 397
398 398 if (childp->cyclehead != 0)
399 399 cycleheadp = childp -> cyclehead;
400 400 else
401 401 cycleheadp = childp;
402 402
403 403 if (childp->parents == 0) {
404 404 (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s"
405 405 " <spontaneous>\n", "", "", "", "", "", "");
406 406 return;
407 407 }
408 408
409 409 sortparents(childp);
410 410
411 411 for (arcp = childp->parents; arcp; arcp = arcp->arc_parentlist) {
412 412 parentp = arcp -> arc_parentp;
413 413 if (childp == parentp || (childp->cycleno != 0 &&
414 414 parentp->cycleno == childp->cycleno)) {
415 415 /*
416 416 * selfcall or call among siblings
417 417 */
418 418 (void) printf(
419 419 "%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
420 420 "", "", "", "", arcp->arc_count, "");
421 421 printname(parentp);
422 422
423 423 if (Cflag)
424 424 print_demangled_name(54, parentp);
425 425
426 426 (void) printf("\n");
427 427 } else {
428 428 /*
429 429 * regular parent of child
430 430 */
431 431 (void) printf(
432 432 "%6.6s %5.5s %7.2f %11.2f %7lld/%-7lld ", "",
433 433 "", arcp->arc_time / hz, arcp->arc_childtime / hz,
434 434 arcp->arc_count, cycleheadp->ncall);
435 435 printname(parentp);
436 436
437 437 if (Cflag)
438 438 print_demangled_name(54, parentp);
439 439
440 440 (void) printf("\n");
441 441 }
442 442 }
443 443 }
444 444
445 445 void
446 446 printchildren(nltype *parentp)
447 447 {
448 448 nltype *childp;
449 449 arctype *arcp;
450 450
451 451 sortchildren(parentp);
452 452
453 453 for (arcp = parentp->children; arcp; arcp = arcp->arc_childlist) {
454 454 childp = arcp->arc_childp;
455 455 if (childp == parentp || (childp->cycleno != 0 &&
456 456 childp->cycleno == parentp->cycleno)) {
457 457 /*
458 458 * self call or call to sibling
459 459 */
460 460 (void) printf(
461 461 "%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
462 462 "", "", "", "", arcp->arc_count, "");
463 463 printname(childp);
464 464
465 465 if (Cflag)
466 466 print_demangled_name(54, childp);
467 467
468 468 (void) printf("\n");
469 469 } else {
470 470 /*
471 471 * regular child of parent
472 472 */
473 473 if (childp->cyclehead)
474 474 (void) printf("%6.6s %5.5s %7.2f %11.2f "
475 475 "%7lld/%-7lld ", "", "",
476 476 arcp->arc_time / hz,
477 477 arcp->arc_childtime / hz, arcp->arc_count,
478 478 childp->cyclehead->ncall);
479 479 else
480 480 (void) printf("%6.6s %5.5s %7.2f %11.2f "
481 481 "%7lld %7.7s ",
482 482 "", "", arcp->arc_time / hz,
483 483 arcp->arc_childtime / hz, arcp->arc_count,
484 484 "");
485 485
486 486 printname(childp);
487 487
488 488 if (Cflag)
489 489 print_demangled_name(54, childp);
490 490
491 491 (void) printf("\n");
492 492 }
↓ open down ↓ |
454 lines elided |
↑ open up ↑ |
493 493 }
494 494 }
495 495
496 496 void
497 497 printname(nltype *selfp)
498 498 {
499 499 const char *c;
500 500 c = demangled_name(selfp);
501 501
502 502 if (selfp->name != 0) {
503 - if (!Cflag)
504 - (void) printf("%s", selfp->name);
505 - else
506 - (void) printf("%s", c);
503 + (void) printf("%s", c);
507 504
508 505 #ifdef DEBUG
509 506 if (debug & DFNDEBUG)
510 507 (void) printf("{%d} ", selfp->toporder);
511 508
512 509 if (debug & PROPDEBUG)
513 510 (void) printf("%5.2f%% ", selfp->propfraction);
514 511 #endif /* DEBUG */
515 512 }
516 513
517 514 if (selfp->cycleno != 0)
518 515 (void) printf("\t<cycle %d>", selfp->cycleno);
519 516
520 517 if (selfp->index != 0) {
521 518 if (selfp->printflag)
522 519 (void) printf(" [%d]", selfp->index);
523 520 else
524 521 (void) printf(" (%d)", selfp->index);
525 522 }
523 +
524 + if (c != selfp->name)
525 + free((void *)c);
526 526 }
527 527
528 528 void
529 529 print_demangled_name(int n, nltype *selfp)
530 530 {
531 - char *c;
531 + char *c = demangled_name(selfp);
532 532 int i;
533 533
534 - c = selfp->name;
535 -
536 - if (strcmp(c, demangled_name(selfp)) == 0)
534 + if (c == selfp->name)
537 535 return;
538 - else {
539 - (void) printf("\n");
540 - for (i = 1; i < n; i++)
541 - (void) printf(" ");
542 - (void) printf("[%s]", selfp->name);
543 - }
536 +
537 + (void) printf("\n");
538 + for (i = 1; i < n; i++)
539 + (void) printf(" ");
540 + (void) printf("[%s]", selfp->name);
541 +
542 + free((void *)c);
544 543 }
545 544
546 545 void
547 546 sortchildren(nltype *parentp)
548 547 {
549 548 arctype *arcp;
550 549 arctype *detachedp;
551 550 arctype sorted;
552 551 arctype *prevp;
553 552
554 553 /*
555 554 * unlink children from parent,
556 555 * then insertion sort back on to sorted's children.
557 556 * *arcp the arc you have detached and are inserting.
558 557 * *detachedp the rest of the arcs to be sorted.
559 558 * sorted arc list onto which you insertion sort.
560 559 * *prevp arc before the arc you are comparing.
561 560 */
562 561 sorted.arc_childlist = 0;
563 562
564 563 /* LINTED: warning: assignment operator */
565 564 for ((arcp = parentp->children) && (detachedp = arcp->arc_childlist);
566 565 arcp;
567 566 /* LINTED: warning: assignment operator */
568 567 (arcp = detachedp) && (detachedp = detachedp->arc_childlist)) {
569 568 /*
570 569 * consider *arcp as disconnected
571 570 * insert it into sorted
572 571 */
573 572 for (prevp = &sorted; prevp->arc_childlist;
574 573 prevp = prevp->arc_childlist) {
575 574 if (arccmp(arcp, prevp->arc_childlist) != LESSTHAN)
576 575 break;
577 576 }
578 577
579 578 arcp->arc_childlist = prevp->arc_childlist;
580 579 prevp->arc_childlist = arcp;
581 580 }
582 581
583 582 /*
584 583 * reattach sorted children to parent
585 584 */
586 585 parentp->children = sorted.arc_childlist;
587 586 }
588 587
589 588 void
590 589 sortparents(nltype *childp)
591 590 {
592 591 arctype *arcp;
593 592 arctype *detachedp;
594 593 arctype sorted;
595 594 arctype *prevp;
596 595
597 596 /*
598 597 * unlink parents from child,
599 598 * then insertion sort back on to sorted's parents.
600 599 * *arcp the arc you have detached and are inserting.
601 600 * *detachedp the rest of the arcs to be sorted.
602 601 * sorted arc list onto which you insertion sort.
603 602 * *prevp arc before the arc you are comparing.
604 603 */
605 604 sorted.arc_parentlist = 0;
606 605
607 606 /* LINTED: warning: assignment operator */
608 607 for ((arcp = childp->parents) && (detachedp = arcp->arc_parentlist);
609 608 arcp;
610 609 /* LINTED: warning: assignment operator */
611 610 (arcp = detachedp) && (detachedp = detachedp->arc_parentlist)) {
612 611 /*
613 612 * consider *arcp as disconnected
614 613 * insert it into sorted
615 614 */
616 615 for (prevp = &sorted; prevp->arc_parentlist;
617 616 prevp = prevp->arc_parentlist) {
618 617 if (arccmp(arcp, prevp->arc_parentlist) != GREATERTHAN)
619 618 break;
620 619 }
621 620 arcp->arc_parentlist = prevp->arc_parentlist;
622 621 prevp->arc_parentlist = arcp;
623 622 }
624 623
625 624 /*
626 625 * reattach sorted arcs to child
627 626 */
628 627 childp->parents = sorted.arc_parentlist;
629 628 }
630 629
631 630 void
632 631 printcycle(nltype *cyclep)
633 632 {
634 633 char kirkbuffer[BUFSIZ];
635 634
636 635 (void) sprintf(kirkbuffer, "[%d]", cyclep->index);
637 636 (void) printf("%-6.6s %5.1f %7.2f %11.2f %7lld", kirkbuffer,
638 637 100 * (cyclep->propself + cyclep->propchild) / printtime,
639 638 cyclep -> propself / hz, cyclep -> propchild / hz,
640 639 cyclep -> ncall);
641 640
642 641 if (cyclep->selfcalls != 0)
643 642 (void) printf("+%-7lld", cyclep->selfcalls);
644 643 else
645 644 (void) printf(" %7.7s", "");
646 645
647 646 (void) printf(" <cycle %d as a whole>\t[%d]\n", cyclep->cycleno,
648 647 cyclep->index);
649 648 }
650 649
651 650 /*
652 651 * print the members of a cycle
653 652 */
654 653 void
655 654 printmembers(nltype *cyclep)
656 655 {
657 656 nltype *memberp;
658 657
659 658 sortmembers(cyclep);
660 659
661 660 for (memberp = cyclep->cnext; memberp; memberp = memberp->cnext) {
662 661 (void) printf("%6.6s %5.5s %7.2f %11.2f %7lld", "", "",
663 662 memberp->propself / hz, memberp->propchild / hz,
664 663 memberp->ncall);
665 664
666 665 if (memberp->selfcalls != 0)
667 666 (void) printf("+%-7lld", memberp->selfcalls);
668 667 else
669 668 (void) printf(" %7.7s", "");
670 669
671 670 (void) printf(" ");
672 671 printname(memberp);
673 672 if (Cflag)
674 673 print_demangled_name(54, memberp);
675 674 (void) printf("\n");
676 675 }
677 676 }
678 677
679 678 /*
680 679 * sort members of a cycle
681 680 */
682 681 void
683 682 sortmembers(nltype *cyclep)
684 683 {
685 684 nltype *todo;
686 685 nltype *doing;
687 686 nltype *prev;
688 687
689 688 /*
690 689 * detach cycle members from cyclehead,
691 690 * and insertion sort them back on.
692 691 */
693 692 todo = cyclep->cnext;
694 693 cyclep->cnext = 0;
695 694
696 695 /* LINTED: warning: assignment operator */
697 696 for ((doing = todo) && (todo = doing->cnext);
698 697 doing;
699 698 /* LINTED: warning: assignment operator */
700 699 (doing = todo) && (todo = doing->cnext)) {
701 700 for (prev = cyclep; prev->cnext; prev = prev->cnext) {
702 701 if (membercmp(doing, prev->cnext) == GREATERTHAN)
703 702 break;
704 703 }
705 704 doing->cnext = prev->cnext;
706 705 prev->cnext = doing;
707 706 }
708 707 }
709 708
710 709 /*
711 710 * major sort is on propself + propchild,
712 711 * next is sort on ncalls + selfcalls.
713 712 */
714 713 int
715 714 membercmp(nltype *this, nltype *that)
716 715 {
717 716 double thistime = this->propself + this->propchild;
718 717 double thattime = that->propself + that->propchild;
719 718 actype thiscalls = this->ncall + this->selfcalls;
720 719 actype thatcalls = that->ncall + that->selfcalls;
721 720
722 721 if (thistime > thattime)
723 722 return (GREATERTHAN);
724 723
725 724 if (thistime < thattime)
726 725 return (LESSTHAN);
727 726
728 727 if (thiscalls > thatcalls)
729 728 return (GREATERTHAN);
730 729
731 730 if (thiscalls < thatcalls)
732 731 return (LESSTHAN);
733 732
734 733 return (EQUALTO);
735 734 }
736 735
737 736 /*
738 737 * compare two arcs to/from the same child/parent.
739 738 * - if one arc is a self arc, it's least.
740 739 * - if one arc is within a cycle, it's less than.
741 740 * - if both arcs are within a cycle, compare arc counts.
742 741 * - if neither arc is within a cycle, compare with
743 742 * arc_time + arc_childtime as major key
744 743 * arc count as minor key
745 744 */
746 745 int
747 746 arccmp(arctype *thisp, arctype *thatp)
748 747 {
749 748 nltype *thisparentp = thisp->arc_parentp;
750 749 nltype *thischildp = thisp->arc_childp;
751 750 nltype *thatparentp = thatp->arc_parentp;
752 751 nltype *thatchildp = thatp->arc_childp;
753 752 double thistime;
754 753 double thattime;
755 754
756 755 #ifdef DEBUG
757 756 if (debug & TIMEDEBUG) {
758 757 (void) printf("[arccmp] ");
759 758 printname(thisparentp);
760 759 (void) printf(" calls ");
761 760 printname(thischildp);
762 761 (void) printf(" %f + %f %lld/%lld\n", thisp->arc_time,
763 762 thisp->arc_childtime, thisp->arc_count,
764 763 thischildp->ncall);
765 764 (void) printf("[arccmp] ");
766 765 printname(thatparentp);
767 766 (void) printf(" calls ");
768 767 printname(thatchildp);
769 768 (void) printf(" %f + %f %lld/%lld\n", thatp->arc_time,
770 769 thatp->arc_childtime, thatp->arc_count,
771 770 thatchildp->ncall);
772 771 (void) printf("\n");
773 772 }
774 773 #endif /* DEBUG */
775 774
776 775 if (thisparentp == thischildp) {
777 776 /*
778 777 * this is a self call
779 778 */
780 779 return (LESSTHAN);
781 780 }
782 781
783 782 if (thatparentp == thatchildp) {
784 783 /*
785 784 * that is a self call
786 785 */
787 786 return (GREATERTHAN);
788 787 }
789 788
790 789 if (thisparentp->cycleno != 0 && thischildp->cycleno != 0 &&
791 790 thisparentp->cycleno == thischildp->cycleno) {
792 791 /*
793 792 * this is a call within a cycle
794 793 */
795 794 if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
796 795 thatparentp->cycleno == thatchildp->cycleno) {
797 796 /*
798 797 * that is a call within the cycle, too
799 798 */
800 799 if (thisp->arc_count < thatp->arc_count)
801 800 return (LESSTHAN);
802 801
803 802 if (thisp->arc_count > thatp->arc_count)
804 803 return (GREATERTHAN);
805 804
806 805 return (EQUALTO);
807 806 } else {
808 807 /*
809 808 * that isn't a call within the cycle
810 809 */
811 810 return (LESSTHAN);
812 811 }
813 812 } else {
814 813 /*
815 814 * this isn't a call within a cycle
816 815 */
817 816 if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
818 817 thatparentp->cycleno == thatchildp->cycleno) {
819 818 /*
820 819 * that is a call within a cycle
821 820 */
822 821 return (GREATERTHAN);
823 822 } else {
824 823 /*
825 824 * neither is a call within a cycle
826 825 */
827 826 thistime = thisp->arc_time + thisp->arc_childtime;
828 827 thattime = thatp->arc_time + thatp->arc_childtime;
829 828
830 829 if (thistime < thattime)
831 830 return (LESSTHAN);
832 831
833 832 if (thistime > thattime)
834 833 return (GREATERTHAN);
835 834
836 835 if (thisp->arc_count < thatp->arc_count)
837 836 return (LESSTHAN);
838 837
839 838 if (thisp->arc_count > thatp->arc_count)
840 839 return (GREATERTHAN);
841 840
842 841 return (EQUALTO);
843 842 }
844 843 }
845 844 }
846 845
847 846 void
848 847 printblurb(char *blurbname)
849 848 {
850 849 FILE *blurbfile;
851 850 int input;
852 851
853 852 blurbfile = fopen(blurbname, "r");
854 853 if (blurbfile == NULL) {
855 854 perror(blurbname);
856 855 return;
857 856 }
858 857
859 858 while ((input = getc(blurbfile)) != EOF)
860 859 (void) putchar(input);
861 860
862 861 (void) fclose(blurbfile);
863 862 }
864 863
865 864 char *s1, *s2;
866 865
867 866 static int
868 867 namecmp(const void *arg1, const void *arg2)
869 868 {
870 869 nltype **npp1 = (nltype **)arg1;
871 870 nltype **npp2 = (nltype **)arg2;
872 871
873 872 if (!Cflag)
874 873 return (strcmp((*npp1)->name, (*npp2)->name));
↓ open down ↓ |
321 lines elided |
↑ open up ↑ |
875 874 else {
876 875 striped_name(s1, npp1);
877 876 striped_name(s2, npp2);
878 877 return (strcmp(s1, s2));
879 878 }
880 879 }
881 880
882 881 void
883 882 striped_name(char *s, nltype **npp)
884 883 {
885 - const char *d;
884 + const char *name, *d;
886 885 char *c;
887 886
888 887 c = (char *)s;
889 - d = demangled_name(*npp);
888 + name = d = demangled_name(*npp);
890 889
891 890 while ((*d != '(') && (*d != '\0')) {
892 891 if (*d != ':')
893 892 *c++ = *d++;
894 893 else
895 894 d++;
896 895 }
897 896 *c = '\0';
897 +
898 + if ((*npp)->name != name)
899 + free((void *)name);
898 900 }
899 901
900 902 /*
901 903 * Checks if the current symbol name is the same as its neighbour and
902 904 * returns TRUE if it is.
903 905 */
904 906 static bool
905 907 does_clash(nltype **nlp, int ndx, int nnames)
906 908 {
907 909 /*
908 910 * same as previous (if there's one) ?
909 911 */
910 912 if (ndx && (strcmp(nlp[ndx]->name, nlp[ndx-1]->name) == 0))
911 913 return (TRUE);
912 914
913 915 /*
914 916 * same as next (if there's one) ?
915 917 */
916 918 if ((ndx < (nnames - 1)) &&
917 919 (strcmp(nlp[ndx]->name, nlp[ndx+1]->name) == 0)) {
918 920 return (TRUE);
919 921 }
920 922
921 923 return (FALSE);
922 924 }
923 925
924 926 void
925 927 printmodules()
926 928 {
927 929 mod_info_t *mi;
928 930
929 931 (void) printf("\f\nObject modules\n\n");
930 932 for (mi = &modules; mi; mi = mi->next)
931 933 (void) printf(" %d: %s\n", mi->id, mi->name);
932 934 }
933 935
934 936 #define IDFMT(id) ((id) < 10 ? 1 : 2)
935 937 #define NMFMT(id) ((id) < 10 ? 17 : 16)
936 938
937 939 void
938 940 printindex()
939 941 {
940 942 nltype **namesortnlp;
941 943 nltype *nlp;
942 944 int index, nnames, todo, i, j;
943 945 char peterbuffer[BUFSIZ];
944 946 mod_info_t *mi;
945 947
946 948 /*
947 949 * Now, sort regular function name alphabetically
948 950 * to create an index.
949 951 */
950 952 namesortnlp = calloc(total_names + ncycle, sizeof (nltype *));
951 953
952 954 if (namesortnlp == NULL)
953 955 (void) fprintf(stderr, "%s: ran out of memory for sorting\n",
954 956 whoami);
955 957
956 958 nnames = 0;
957 959 for (mi = &modules; mi; mi = mi->next) {
958 960 for (index = 0; index < mi->nname; index++) {
959 961 if (zflag == 0 && (mi->nl[index]).ncall == 0 &&
960 962 (mi->nl[index]).time == 0) {
961 963 continue;
962 964 }
963 965
964 966 /*
965 967 * Do not print certain special symbols, like
966 968 * PRF_EXTSYM, etc. even if zflag was on.
967 969 */
968 970 if (is_special_sym(&(mi->nl[index])))
969 971 continue;
970 972
971 973 namesortnlp[nnames++] = &(mi->nl[index]);
972 974 }
973 975 }
974 976
975 977 if (Cflag) {
976 978 s1 = malloc(500 * sizeof (char));
977 979 s2 = malloc(500 * sizeof (char));
978 980 }
979 981
980 982 qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
981 983
982 984 for (index = 1, todo = nnames; index <= ncycle; index++)
983 985 namesortnlp[todo++] = &cyclenl[index];
984 986
985 987 (void) printf("\f\nIndex by function name\n\n");
986 988
987 989 if (!Cflag)
988 990 index = (todo + 2) / 3;
989 991 else
990 992 index = todo;
991 993
992 994 for (i = 0; i < index; i++) {
993 995 if (!Cflag) {
994 996 for (j = i; j < todo; j += index) {
995 997 nlp = namesortnlp[j];
996 998
997 999 if (nlp->printflag) {
998 1000 (void) sprintf(peterbuffer,
999 1001 "[%d]", nlp->index);
1000 1002 } else {
1001 1003 (void) sprintf(peterbuffer,
1002 1004 "(%d)", nlp->index);
1003 1005 }
1004 1006
1005 1007 if (j < nnames) {
1006 1008 if (does_clash(namesortnlp,
1007 1009 j, nnames)) {
1008 1010 (void) printf(
1009 1011 "%6.6s %*d:%-*.*s",
1010 1012 peterbuffer,
1011 1013 IDFMT(nlp->module->id),
1012 1014 nlp->module->id,
1013 1015 NMFMT(nlp->module->id),
1014 1016 NMFMT(nlp->module->id),
1015 1017 nlp->name);
1016 1018 } else {
1017 1019 (void) printf("%6.6s %-19.19s",
1018 1020 peterbuffer, nlp->name);
1019 1021 }
1020 1022 } else {
1021 1023 (void) printf("%6.6s ", peterbuffer);
1022 1024 (void) sprintf(peterbuffer,
1023 1025 "<cycle %d>", nlp->cycleno);
1024 1026 (void) printf("%-19.19s", peterbuffer);
1025 1027 }
1026 1028 }
1027 1029 } else {
1028 1030 nlp = namesortnlp[i];
1029 1031
1030 1032 if (nlp->printflag)
1031 1033 (void) sprintf(peterbuffer, "[%d]", nlp->index);
1032 1034 else
1033 1035 (void) sprintf(peterbuffer, "(%d)", nlp->index);
1034 1036
1035 1037 if (i < nnames) {
1036 1038 const char *d = demangled_name(nlp);
1037 1039
1038 1040 if (does_clash(namesortnlp, i, nnames)) {
1039 1041 (void) printf("%6.6s %d:%s\n",
1040 1042 peterbuffer, nlp->module->id, d);
1041 1043 } else
1042 1044 (void) printf("%6.6s %s\n", peterbuffer,
1043 1045 d);
1044 1046
1045 1047 if (d != nlp->name)
1046 1048 (void) printf("%6.6s [%s]", "",
1047 1049 nlp->name);
1048 1050 } else {
1049 1051 (void) printf("%6.6s ", peterbuffer);
1050 1052 (void) sprintf(peterbuffer, "<cycle %d>",
1051 1053 nlp->cycleno);
1052 1054 (void) printf("%-33.33s", peterbuffer);
1053 1055 }
1054 1056 }
1055 1057 (void) printf("\n");
1056 1058 }
1057 1059 free(namesortnlp);
1058 1060 }
↓ open down ↓ |
151 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX