Print this page
cleanup
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.
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 25 *
26 26 * Copyright 2018 Jason King
27 27 */
28 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 }
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 503 (void) printf("%s", c);
504 504
505 505 #ifdef DEBUG
506 506 if (debug & DFNDEBUG)
507 507 (void) printf("{%d} ", selfp->toporder);
508 508
509 509 if (debug & PROPDEBUG)
510 510 (void) printf("%5.2f%% ", selfp->propfraction);
511 511 #endif /* DEBUG */
512 512 }
513 513
514 514 if (selfp->cycleno != 0)
515 515 (void) printf("\t<cycle %d>", selfp->cycleno);
516 516
517 517 if (selfp->index != 0) {
518 518 if (selfp->printflag)
519 519 (void) printf(" [%d]", selfp->index);
520 520 else
↓ open down ↓ |
520 lines elided |
↑ open up ↑ |
521 521 (void) printf(" (%d)", selfp->index);
522 522 }
523 523
524 524 if (c != selfp->name)
525 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 = demangled_name(selfp);
531 + char *c = (char *)demangled_name(selfp);
532 532 int i;
533 533
534 534 if (c == selfp->name)
535 535 return;
536 536
537 537 (void) printf("\n");
538 538 for (i = 1; i < n; i++)
539 539 (void) printf(" ");
540 540 (void) printf("[%s]", selfp->name);
541 541
542 - free((void *)c);
542 + free(c);
543 543 }
544 544
545 545 void
546 546 sortchildren(nltype *parentp)
547 547 {
548 548 arctype *arcp;
549 549 arctype *detachedp;
550 550 arctype sorted;
551 551 arctype *prevp;
552 552
553 553 /*
554 554 * unlink children from parent,
555 555 * then insertion sort back on to sorted's children.
556 556 * *arcp the arc you have detached and are inserting.
557 557 * *detachedp the rest of the arcs to be sorted.
558 558 * sorted arc list onto which you insertion sort.
559 559 * *prevp arc before the arc you are comparing.
560 560 */
561 561 sorted.arc_childlist = 0;
562 562
563 563 /* LINTED: warning: assignment operator */
564 564 for ((arcp = parentp->children) && (detachedp = arcp->arc_childlist);
565 565 arcp;
566 566 /* LINTED: warning: assignment operator */
567 567 (arcp = detachedp) && (detachedp = detachedp->arc_childlist)) {
568 568 /*
569 569 * consider *arcp as disconnected
570 570 * insert it into sorted
571 571 */
572 572 for (prevp = &sorted; prevp->arc_childlist;
573 573 prevp = prevp->arc_childlist) {
574 574 if (arccmp(arcp, prevp->arc_childlist) != LESSTHAN)
575 575 break;
576 576 }
577 577
578 578 arcp->arc_childlist = prevp->arc_childlist;
579 579 prevp->arc_childlist = arcp;
580 580 }
581 581
582 582 /*
583 583 * reattach sorted children to parent
584 584 */
585 585 parentp->children = sorted.arc_childlist;
586 586 }
587 587
588 588 void
589 589 sortparents(nltype *childp)
590 590 {
591 591 arctype *arcp;
592 592 arctype *detachedp;
593 593 arctype sorted;
594 594 arctype *prevp;
595 595
596 596 /*
597 597 * unlink parents from child,
598 598 * then insertion sort back on to sorted's parents.
599 599 * *arcp the arc you have detached and are inserting.
600 600 * *detachedp the rest of the arcs to be sorted.
601 601 * sorted arc list onto which you insertion sort.
602 602 * *prevp arc before the arc you are comparing.
603 603 */
604 604 sorted.arc_parentlist = 0;
605 605
606 606 /* LINTED: warning: assignment operator */
607 607 for ((arcp = childp->parents) && (detachedp = arcp->arc_parentlist);
608 608 arcp;
609 609 /* LINTED: warning: assignment operator */
610 610 (arcp = detachedp) && (detachedp = detachedp->arc_parentlist)) {
611 611 /*
612 612 * consider *arcp as disconnected
613 613 * insert it into sorted
614 614 */
615 615 for (prevp = &sorted; prevp->arc_parentlist;
616 616 prevp = prevp->arc_parentlist) {
617 617 if (arccmp(arcp, prevp->arc_parentlist) != GREATERTHAN)
618 618 break;
619 619 }
620 620 arcp->arc_parentlist = prevp->arc_parentlist;
621 621 prevp->arc_parentlist = arcp;
622 622 }
623 623
624 624 /*
625 625 * reattach sorted arcs to child
626 626 */
627 627 childp->parents = sorted.arc_parentlist;
628 628 }
629 629
630 630 void
631 631 printcycle(nltype *cyclep)
632 632 {
633 633 char kirkbuffer[BUFSIZ];
634 634
635 635 (void) sprintf(kirkbuffer, "[%d]", cyclep->index);
636 636 (void) printf("%-6.6s %5.1f %7.2f %11.2f %7lld", kirkbuffer,
637 637 100 * (cyclep->propself + cyclep->propchild) / printtime,
638 638 cyclep -> propself / hz, cyclep -> propchild / hz,
639 639 cyclep -> ncall);
640 640
641 641 if (cyclep->selfcalls != 0)
642 642 (void) printf("+%-7lld", cyclep->selfcalls);
643 643 else
644 644 (void) printf(" %7.7s", "");
645 645
646 646 (void) printf(" <cycle %d as a whole>\t[%d]\n", cyclep->cycleno,
647 647 cyclep->index);
648 648 }
649 649
650 650 /*
651 651 * print the members of a cycle
652 652 */
653 653 void
654 654 printmembers(nltype *cyclep)
655 655 {
656 656 nltype *memberp;
657 657
658 658 sortmembers(cyclep);
659 659
660 660 for (memberp = cyclep->cnext; memberp; memberp = memberp->cnext) {
661 661 (void) printf("%6.6s %5.5s %7.2f %11.2f %7lld", "", "",
662 662 memberp->propself / hz, memberp->propchild / hz,
663 663 memberp->ncall);
664 664
665 665 if (memberp->selfcalls != 0)
666 666 (void) printf("+%-7lld", memberp->selfcalls);
667 667 else
668 668 (void) printf(" %7.7s", "");
669 669
670 670 (void) printf(" ");
671 671 printname(memberp);
672 672 if (Cflag)
673 673 print_demangled_name(54, memberp);
674 674 (void) printf("\n");
675 675 }
676 676 }
677 677
678 678 /*
679 679 * sort members of a cycle
680 680 */
681 681 void
682 682 sortmembers(nltype *cyclep)
683 683 {
684 684 nltype *todo;
685 685 nltype *doing;
686 686 nltype *prev;
687 687
688 688 /*
689 689 * detach cycle members from cyclehead,
690 690 * and insertion sort them back on.
691 691 */
692 692 todo = cyclep->cnext;
693 693 cyclep->cnext = 0;
694 694
695 695 /* LINTED: warning: assignment operator */
696 696 for ((doing = todo) && (todo = doing->cnext);
697 697 doing;
698 698 /* LINTED: warning: assignment operator */
699 699 (doing = todo) && (todo = doing->cnext)) {
700 700 for (prev = cyclep; prev->cnext; prev = prev->cnext) {
701 701 if (membercmp(doing, prev->cnext) == GREATERTHAN)
702 702 break;
703 703 }
704 704 doing->cnext = prev->cnext;
705 705 prev->cnext = doing;
706 706 }
707 707 }
708 708
709 709 /*
710 710 * major sort is on propself + propchild,
711 711 * next is sort on ncalls + selfcalls.
712 712 */
713 713 int
714 714 membercmp(nltype *this, nltype *that)
715 715 {
716 716 double thistime = this->propself + this->propchild;
717 717 double thattime = that->propself + that->propchild;
718 718 actype thiscalls = this->ncall + this->selfcalls;
719 719 actype thatcalls = that->ncall + that->selfcalls;
720 720
721 721 if (thistime > thattime)
722 722 return (GREATERTHAN);
723 723
724 724 if (thistime < thattime)
725 725 return (LESSTHAN);
726 726
727 727 if (thiscalls > thatcalls)
728 728 return (GREATERTHAN);
729 729
730 730 if (thiscalls < thatcalls)
731 731 return (LESSTHAN);
732 732
733 733 return (EQUALTO);
734 734 }
735 735
736 736 /*
737 737 * compare two arcs to/from the same child/parent.
738 738 * - if one arc is a self arc, it's least.
739 739 * - if one arc is within a cycle, it's less than.
740 740 * - if both arcs are within a cycle, compare arc counts.
741 741 * - if neither arc is within a cycle, compare with
742 742 * arc_time + arc_childtime as major key
743 743 * arc count as minor key
744 744 */
745 745 int
746 746 arccmp(arctype *thisp, arctype *thatp)
747 747 {
748 748 nltype *thisparentp = thisp->arc_parentp;
749 749 nltype *thischildp = thisp->arc_childp;
750 750 nltype *thatparentp = thatp->arc_parentp;
751 751 nltype *thatchildp = thatp->arc_childp;
752 752 double thistime;
753 753 double thattime;
754 754
755 755 #ifdef DEBUG
756 756 if (debug & TIMEDEBUG) {
757 757 (void) printf("[arccmp] ");
758 758 printname(thisparentp);
759 759 (void) printf(" calls ");
760 760 printname(thischildp);
761 761 (void) printf(" %f + %f %lld/%lld\n", thisp->arc_time,
762 762 thisp->arc_childtime, thisp->arc_count,
763 763 thischildp->ncall);
764 764 (void) printf("[arccmp] ");
765 765 printname(thatparentp);
766 766 (void) printf(" calls ");
767 767 printname(thatchildp);
768 768 (void) printf(" %f + %f %lld/%lld\n", thatp->arc_time,
769 769 thatp->arc_childtime, thatp->arc_count,
770 770 thatchildp->ncall);
771 771 (void) printf("\n");
772 772 }
773 773 #endif /* DEBUG */
774 774
775 775 if (thisparentp == thischildp) {
776 776 /*
777 777 * this is a self call
778 778 */
779 779 return (LESSTHAN);
780 780 }
781 781
782 782 if (thatparentp == thatchildp) {
783 783 /*
784 784 * that is a self call
785 785 */
786 786 return (GREATERTHAN);
787 787 }
788 788
789 789 if (thisparentp->cycleno != 0 && thischildp->cycleno != 0 &&
790 790 thisparentp->cycleno == thischildp->cycleno) {
791 791 /*
792 792 * this is a call within a cycle
793 793 */
794 794 if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
795 795 thatparentp->cycleno == thatchildp->cycleno) {
796 796 /*
797 797 * that is a call within the cycle, too
798 798 */
799 799 if (thisp->arc_count < thatp->arc_count)
800 800 return (LESSTHAN);
801 801
802 802 if (thisp->arc_count > thatp->arc_count)
803 803 return (GREATERTHAN);
804 804
805 805 return (EQUALTO);
806 806 } else {
807 807 /*
808 808 * that isn't a call within the cycle
809 809 */
810 810 return (LESSTHAN);
811 811 }
812 812 } else {
813 813 /*
814 814 * this isn't a call within a cycle
815 815 */
816 816 if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
817 817 thatparentp->cycleno == thatchildp->cycleno) {
818 818 /*
819 819 * that is a call within a cycle
820 820 */
821 821 return (GREATERTHAN);
822 822 } else {
823 823 /*
824 824 * neither is a call within a cycle
825 825 */
826 826 thistime = thisp->arc_time + thisp->arc_childtime;
827 827 thattime = thatp->arc_time + thatp->arc_childtime;
828 828
829 829 if (thistime < thattime)
830 830 return (LESSTHAN);
831 831
832 832 if (thistime > thattime)
833 833 return (GREATERTHAN);
834 834
835 835 if (thisp->arc_count < thatp->arc_count)
836 836 return (LESSTHAN);
837 837
838 838 if (thisp->arc_count > thatp->arc_count)
839 839 return (GREATERTHAN);
840 840
841 841 return (EQUALTO);
842 842 }
843 843 }
844 844 }
845 845
846 846 void
847 847 printblurb(char *blurbname)
848 848 {
849 849 FILE *blurbfile;
850 850 int input;
851 851
852 852 blurbfile = fopen(blurbname, "r");
853 853 if (blurbfile == NULL) {
854 854 perror(blurbname);
855 855 return;
856 856 }
857 857
858 858 while ((input = getc(blurbfile)) != EOF)
859 859 (void) putchar(input);
860 860
861 861 (void) fclose(blurbfile);
862 862 }
863 863
864 864 char *s1, *s2;
865 865
866 866 static int
867 867 namecmp(const void *arg1, const void *arg2)
868 868 {
869 869 nltype **npp1 = (nltype **)arg1;
870 870 nltype **npp2 = (nltype **)arg2;
871 871
872 872 if (!Cflag)
873 873 return (strcmp((*npp1)->name, (*npp2)->name));
874 874 else {
875 875 striped_name(s1, npp1);
876 876 striped_name(s2, npp2);
877 877 return (strcmp(s1, s2));
878 878 }
879 879 }
880 880
881 881 void
882 882 striped_name(char *s, nltype **npp)
883 883 {
884 884 const char *name, *d;
885 885 char *c;
886 886
887 887 c = (char *)s;
888 888 name = d = demangled_name(*npp);
889 889
890 890 while ((*d != '(') && (*d != '\0')) {
891 891 if (*d != ':')
892 892 *c++ = *d++;
893 893 else
894 894 d++;
895 895 }
896 896 *c = '\0';
897 897
898 898 if ((*npp)->name != name)
899 899 free((void *)name);
900 900 }
901 901
902 902 /*
903 903 * Checks if the current symbol name is the same as its neighbour and
904 904 * returns TRUE if it is.
905 905 */
906 906 static bool
907 907 does_clash(nltype **nlp, int ndx, int nnames)
908 908 {
909 909 /*
910 910 * same as previous (if there's one) ?
911 911 */
912 912 if (ndx && (strcmp(nlp[ndx]->name, nlp[ndx-1]->name) == 0))
913 913 return (TRUE);
914 914
915 915 /*
916 916 * same as next (if there's one) ?
917 917 */
918 918 if ((ndx < (nnames - 1)) &&
919 919 (strcmp(nlp[ndx]->name, nlp[ndx+1]->name) == 0)) {
920 920 return (TRUE);
921 921 }
922 922
923 923 return (FALSE);
924 924 }
925 925
926 926 void
927 927 printmodules()
928 928 {
929 929 mod_info_t *mi;
930 930
931 931 (void) printf("\f\nObject modules\n\n");
932 932 for (mi = &modules; mi; mi = mi->next)
933 933 (void) printf(" %d: %s\n", mi->id, mi->name);
934 934 }
935 935
936 936 #define IDFMT(id) ((id) < 10 ? 1 : 2)
937 937 #define NMFMT(id) ((id) < 10 ? 17 : 16)
938 938
939 939 void
940 940 printindex()
941 941 {
942 942 nltype **namesortnlp;
943 943 nltype *nlp;
944 944 int index, nnames, todo, i, j;
945 945 char peterbuffer[BUFSIZ];
946 946 mod_info_t *mi;
947 947
948 948 /*
949 949 * Now, sort regular function name alphabetically
950 950 * to create an index.
951 951 */
952 952 namesortnlp = calloc(total_names + ncycle, sizeof (nltype *));
953 953
954 954 if (namesortnlp == NULL)
955 955 (void) fprintf(stderr, "%s: ran out of memory for sorting\n",
956 956 whoami);
957 957
958 958 nnames = 0;
959 959 for (mi = &modules; mi; mi = mi->next) {
960 960 for (index = 0; index < mi->nname; index++) {
961 961 if (zflag == 0 && (mi->nl[index]).ncall == 0 &&
962 962 (mi->nl[index]).time == 0) {
963 963 continue;
964 964 }
965 965
966 966 /*
967 967 * Do not print certain special symbols, like
968 968 * PRF_EXTSYM, etc. even if zflag was on.
969 969 */
970 970 if (is_special_sym(&(mi->nl[index])))
971 971 continue;
972 972
973 973 namesortnlp[nnames++] = &(mi->nl[index]);
974 974 }
975 975 }
976 976
977 977 if (Cflag) {
978 978 s1 = malloc(500 * sizeof (char));
979 979 s2 = malloc(500 * sizeof (char));
980 980 }
981 981
982 982 qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
983 983
984 984 for (index = 1, todo = nnames; index <= ncycle; index++)
985 985 namesortnlp[todo++] = &cyclenl[index];
986 986
987 987 (void) printf("\f\nIndex by function name\n\n");
988 988
989 989 if (!Cflag)
990 990 index = (todo + 2) / 3;
991 991 else
992 992 index = todo;
993 993
994 994 for (i = 0; i < index; i++) {
995 995 if (!Cflag) {
996 996 for (j = i; j < todo; j += index) {
997 997 nlp = namesortnlp[j];
998 998
999 999 if (nlp->printflag) {
1000 1000 (void) sprintf(peterbuffer,
1001 1001 "[%d]", nlp->index);
1002 1002 } else {
1003 1003 (void) sprintf(peterbuffer,
1004 1004 "(%d)", nlp->index);
1005 1005 }
1006 1006
1007 1007 if (j < nnames) {
1008 1008 if (does_clash(namesortnlp,
1009 1009 j, nnames)) {
1010 1010 (void) printf(
1011 1011 "%6.6s %*d:%-*.*s",
1012 1012 peterbuffer,
1013 1013 IDFMT(nlp->module->id),
1014 1014 nlp->module->id,
1015 1015 NMFMT(nlp->module->id),
1016 1016 NMFMT(nlp->module->id),
1017 1017 nlp->name);
1018 1018 } else {
1019 1019 (void) printf("%6.6s %-19.19s",
1020 1020 peterbuffer, nlp->name);
1021 1021 }
1022 1022 } else {
1023 1023 (void) printf("%6.6s ", peterbuffer);
1024 1024 (void) sprintf(peterbuffer,
1025 1025 "<cycle %d>", nlp->cycleno);
1026 1026 (void) printf("%-19.19s", peterbuffer);
1027 1027 }
1028 1028 }
1029 1029 } else {
1030 1030 nlp = namesortnlp[i];
1031 1031
1032 1032 if (nlp->printflag)
↓ open down ↓ |
480 lines elided |
↑ open up ↑ |
1033 1033 (void) sprintf(peterbuffer, "[%d]", nlp->index);
1034 1034 else
1035 1035 (void) sprintf(peterbuffer, "(%d)", nlp->index);
1036 1036
1037 1037 if (i < nnames) {
1038 1038 const char *d = demangled_name(nlp);
1039 1039
1040 1040 if (does_clash(namesortnlp, i, nnames)) {
1041 1041 (void) printf("%6.6s %d:%s\n",
1042 1042 peterbuffer, nlp->module->id, d);
1043 - } else
1043 + } else {
1044 1044 (void) printf("%6.6s %s\n", peterbuffer,
1045 1045 d);
1046 + }
1046 1047
1047 - if (d != nlp->name)
1048 + if (d != nlp->name) {
1048 1049 (void) printf("%6.6s [%s]", "",
1049 1050 nlp->name);
1051 + free((void *)d);
1052 + }
1050 1053 } else {
1051 1054 (void) printf("%6.6s ", peterbuffer);
1052 1055 (void) sprintf(peterbuffer, "<cycle %d>",
1053 1056 nlp->cycleno);
1054 1057 (void) printf("%-33.33s", peterbuffer);
1055 1058 }
1056 1059 }
1057 1060 (void) printf("\n");
1058 1061 }
1059 1062 free(namesortnlp);
1060 1063 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX