17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
567298654Sdamico * Common Development and Distribution License (the "License").
667298654Sdamico * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
2192ed1782Smike_s
227c478bd9Sstevel@tonic-gate /*
23*b9bd317cSab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2492ed1782Smike_s * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #include <ctype.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
33*b9bd317cSab196087 #include "conv.h"
347c478bd9Sstevel@tonic-gate #include "gprof.h"
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate void print_demangled_name(int, nltype *);
377c478bd9Sstevel@tonic-gate void striped_name(char *, nltype **);
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate extern long hz;
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate * Symbols that must never be printed, no matter what.
437c478bd9Sstevel@tonic-gate */
447c478bd9Sstevel@tonic-gate char *splsym[] = {
457c478bd9Sstevel@tonic-gate PRF_ETEXT,
467c478bd9Sstevel@tonic-gate PRF_EXTSYM,
477c478bd9Sstevel@tonic-gate PRF_MEMTERM,
4892ed1782Smike_s NULL
497c478bd9Sstevel@tonic-gate };
507c478bd9Sstevel@tonic-gate
5192ed1782Smike_s static bool is_special_sym(nltype *nlp);
5292ed1782Smike_s
53*b9bd317cSab196087 const char *
demangled_name(nltype * selfp)547c478bd9Sstevel@tonic-gate demangled_name(nltype *selfp)
557c478bd9Sstevel@tonic-gate {
567c478bd9Sstevel@tonic-gate if (!Cflag)
577c478bd9Sstevel@tonic-gate return (selfp->name);
587c478bd9Sstevel@tonic-gate
59*b9bd317cSab196087 return (conv_demangle_name(selfp->name));
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate void
printprof(void)6392ed1782Smike_s printprof(void)
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate nltype *np;
667c478bd9Sstevel@tonic-gate nltype **sortednlp;
677c478bd9Sstevel@tonic-gate int i, index;
687c478bd9Sstevel@tonic-gate int print_count = number_funcs_toprint;
697c478bd9Sstevel@tonic-gate bool print_flag = TRUE;
707c478bd9Sstevel@tonic-gate mod_info_t *mi;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate actime = 0.0;
7392ed1782Smike_s (void) printf("\f\n");
747c478bd9Sstevel@tonic-gate flatprofheader();
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate /*
777c478bd9Sstevel@tonic-gate * Sort the symbol table in by time
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate sortednlp = (nltype **) calloc(total_names, sizeof (nltype *));
807c478bd9Sstevel@tonic-gate if (sortednlp == (nltype **) 0) {
8192ed1782Smike_s (void) fprintf(stderr,
827c478bd9Sstevel@tonic-gate "[printprof] ran out of memory for time sorting\n");
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate index = 0;
867c478bd9Sstevel@tonic-gate for (mi = &modules; mi; mi = mi->next) {
877c478bd9Sstevel@tonic-gate for (i = 0; i < mi->nname; i++)
887c478bd9Sstevel@tonic-gate sortednlp[index++] = &(mi->nl[i]);
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate
9192ed1782Smike_s qsort(sortednlp, total_names, sizeof (nltype *), timecmp);
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate for (index = 0; (index < total_names) && print_flag; index += 1) {
947c478bd9Sstevel@tonic-gate np = sortednlp[index];
957c478bd9Sstevel@tonic-gate flatprofline(np);
967c478bd9Sstevel@tonic-gate if (nflag) {
977c478bd9Sstevel@tonic-gate if (--print_count == 0)
987c478bd9Sstevel@tonic-gate print_flag = FALSE;
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate actime = 0.0;
1027c478bd9Sstevel@tonic-gate free(sortednlp);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate int
timecmp(const void * arg1,const void * arg2)10692ed1782Smike_s timecmp(const void *arg1, const void *arg2)
1077c478bd9Sstevel@tonic-gate {
10892ed1782Smike_s nltype **npp1 = (nltype **)arg1;
10992ed1782Smike_s nltype **npp2 = (nltype **)arg2;
1107c478bd9Sstevel@tonic-gate double timediff;
1117c478bd9Sstevel@tonic-gate long calldiff;
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate timediff = (*npp2)->time - (*npp1)->time;
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate if (timediff > 0.0)
1167c478bd9Sstevel@tonic-gate return (1);
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate if (timediff < 0.0)
1197c478bd9Sstevel@tonic-gate return (-1);
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate calldiff = (*npp2)->ncall - (*npp1)->ncall;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate if (calldiff > 0)
1247c478bd9Sstevel@tonic-gate return (1);
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate if (calldiff < 0)
1277c478bd9Sstevel@tonic-gate return (-1);
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate return (strcmp((*npp1)->name, (*npp2)->name));
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate * header for flatprofline
1347c478bd9Sstevel@tonic-gate */
1357c478bd9Sstevel@tonic-gate void
flatprofheader()1367c478bd9Sstevel@tonic-gate flatprofheader()
1377c478bd9Sstevel@tonic-gate {
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate if (bflag)
1407c478bd9Sstevel@tonic-gate printblurb(FLAT_BLURB);
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate if (old_style) {
14392ed1782Smike_s (void) printf(
14492ed1782Smike_s "\ngranularity: each sample hit covers %d byte(s)",
1457c478bd9Sstevel@tonic-gate (long)scale * sizeof (UNIT));
1467c478bd9Sstevel@tonic-gate if (totime > 0.0) {
14792ed1782Smike_s (void) printf(" for %.2f%% of %.2f seconds\n\n",
1487c478bd9Sstevel@tonic-gate 100.0/totime, totime / hz);
1497c478bd9Sstevel@tonic-gate } else {
15092ed1782Smike_s (void) printf(" no time accumulated\n\n");
1517c478bd9Sstevel@tonic-gate /*
1527c478bd9Sstevel@tonic-gate * this doesn't hurt since all the numerators will
1537c478bd9Sstevel@tonic-gate * be zero.
1547c478bd9Sstevel@tonic-gate */
1557c478bd9Sstevel@tonic-gate totime = 1.0;
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate
15992ed1782Smike_s (void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
1607c478bd9Sstevel@tonic-gate "% ", "cumulative", "self ", "", "self ", "total ", "");
16192ed1782Smike_s (void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
1627c478bd9Sstevel@tonic-gate "time", "seconds ", "seconds", "calls",
1637c478bd9Sstevel@tonic-gate "ms/call", "ms/call", "name");
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate void
flatprofline(nltype * np)1677c478bd9Sstevel@tonic-gate flatprofline(nltype *np)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate if (zflag == 0 && np->ncall == 0 && np->time == 0)
1707c478bd9Sstevel@tonic-gate return;
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate * Do not print certain special symbols, like PRF_EXTSYM, etc.
1747c478bd9Sstevel@tonic-gate * even if zflag was on.
1757c478bd9Sstevel@tonic-gate */
1767c478bd9Sstevel@tonic-gate if (is_special_sym(np))
1777c478bd9Sstevel@tonic-gate return;
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate actime += np->time;
1807c478bd9Sstevel@tonic-gate
18192ed1782Smike_s (void) printf("%5.1f %10.2f %8.2f",
1827c478bd9Sstevel@tonic-gate 100 * np->time / totime, actime / hz, np->time / hz);
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate if (np->ncall != 0) {
18592ed1782Smike_s (void) printf(" %8lld %8.2f %8.2f ", np->ncall,
1867c478bd9Sstevel@tonic-gate 1000 * np->time / hz / np->ncall,
1877c478bd9Sstevel@tonic-gate 1000 * (np->time + np->childtime) / hz / np->ncall);
1887c478bd9Sstevel@tonic-gate } else {
1897c478bd9Sstevel@tonic-gate if (!Cflag)
19092ed1782Smike_s (void) printf(" %8.8s %8.8s %8.8s ", "", "", "");
1917c478bd9Sstevel@tonic-gate else
19292ed1782Smike_s (void) printf(" %8.8s %8.8s %8.8s ", "", "", "");
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate printname(np);
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate if (Cflag)
1987c478bd9Sstevel@tonic-gate print_demangled_name(55, np);
1997c478bd9Sstevel@tonic-gate
20092ed1782Smike_s (void) printf("\n");
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate void
gprofheader()2047c478bd9Sstevel@tonic-gate gprofheader()
2057c478bd9Sstevel@tonic-gate {
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate if (bflag)
2087c478bd9Sstevel@tonic-gate printblurb(CALLG_BLURB);
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate if (old_style) {
2117c478bd9Sstevel@tonic-gate
21292ed1782Smike_s (void) printf(
21392ed1782Smike_s "\ngranularity: each sample hit covers %d byte(s)",
2147c478bd9Sstevel@tonic-gate (long)scale * sizeof (UNIT));
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate if (printtime > 0.0) {
21792ed1782Smike_s (void) printf(" for %.2f%% of %.2f seconds\n\n",
2187c478bd9Sstevel@tonic-gate 100.0/printtime, printtime / hz);
2197c478bd9Sstevel@tonic-gate } else {
22092ed1782Smike_s (void) printf(" no time propagated\n\n");
2217c478bd9Sstevel@tonic-gate /*
2227c478bd9Sstevel@tonic-gate * this doesn't hurt, since all the numerators
2237c478bd9Sstevel@tonic-gate * will be 0.0
2247c478bd9Sstevel@tonic-gate */
2257c478bd9Sstevel@tonic-gate printtime = 1.0;
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate } else {
22892ed1782Smike_s (void) printf(
22992ed1782Smike_s "\ngranularity: each pc-hit is considered 1 tick");
2307c478bd9Sstevel@tonic-gate if (hz != 1) {
23192ed1782Smike_s (void) printf(" (@ %4.3f seconds per tick)",
2327c478bd9Sstevel@tonic-gate (double)1.0 / hz);
2337c478bd9Sstevel@tonic-gate }
23492ed1782Smike_s (void) puts("\n\n");
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate
23792ed1782Smike_s (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
2387c478bd9Sstevel@tonic-gate "", "", "", "", "called", "total", "parents");
23992ed1782Smike_s (void) printf("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
2407c478bd9Sstevel@tonic-gate "index", "%time", "self", "descendents",
2417c478bd9Sstevel@tonic-gate "called", "self", "name", "index");
24292ed1782Smike_s (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
2437c478bd9Sstevel@tonic-gate "", "", "", "", "called", "total", "children");
24492ed1782Smike_s (void) printf("\n");
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate void
gprofline(nltype * np)2487c478bd9Sstevel@tonic-gate gprofline(nltype *np)
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate char kirkbuffer[BUFSIZ];
2517c478bd9Sstevel@tonic-gate
25292ed1782Smike_s (void) sprintf(kirkbuffer, "[%d]", np->index);
25392ed1782Smike_s (void) printf("%-6.6s %5.1f %7.2f %11.2f", kirkbuffer,
2547c478bd9Sstevel@tonic-gate 100 * (np->propself + np->propchild) / printtime,
2557c478bd9Sstevel@tonic-gate np->propself / hz, np->propchild / hz);
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate if ((np->ncall + np->selfcalls) != 0) {
25892ed1782Smike_s (void) printf(" %7lld", np->ncall);
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate if (np->selfcalls != 0)
26192ed1782Smike_s (void) printf("+%-7lld ", np->selfcalls);
2627c478bd9Sstevel@tonic-gate else
26392ed1782Smike_s (void) printf(" %7.7s ", "");
2647c478bd9Sstevel@tonic-gate } else {
26592ed1782Smike_s (void) printf(" %7.7s %7.7s ", "", "");
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate printname(np);
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate if (Cflag)
2717c478bd9Sstevel@tonic-gate print_demangled_name(50, np);
2727c478bd9Sstevel@tonic-gate
27392ed1782Smike_s (void) printf("\n");
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
2767c478bd9Sstevel@tonic-gate static bool
is_special_sym(nltype * nlp)2777c478bd9Sstevel@tonic-gate is_special_sym(nltype *nlp)
2787c478bd9Sstevel@tonic-gate {
2797c478bd9Sstevel@tonic-gate int i;
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate if (nlp->name == NULL)
2827c478bd9Sstevel@tonic-gate return (FALSE);
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate for (i = 0; splsym[i]; i++)
2857c478bd9Sstevel@tonic-gate if (strcmp(splsym[i], nlp->name) == 0)
2867c478bd9Sstevel@tonic-gate return (TRUE);
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate return (FALSE);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate void
printgprof(nltype ** timesortnlp)2927c478bd9Sstevel@tonic-gate printgprof(nltype **timesortnlp)
2937c478bd9Sstevel@tonic-gate {
2947c478bd9Sstevel@tonic-gate int index;
2957c478bd9Sstevel@tonic-gate nltype *parentp;
2967c478bd9Sstevel@tonic-gate int print_count = number_funcs_toprint;
2977c478bd9Sstevel@tonic-gate bool count_flag = TRUE;
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate /*
3007c478bd9Sstevel@tonic-gate * Print out the structured profiling list
3017c478bd9Sstevel@tonic-gate */
3027c478bd9Sstevel@tonic-gate gprofheader();
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate for (index = 0; index < total_names + ncycle && count_flag; index++) {
3057c478bd9Sstevel@tonic-gate parentp = timesortnlp[index];
3067c478bd9Sstevel@tonic-gate if (zflag == 0 && parentp->ncall == 0 &&
3077c478bd9Sstevel@tonic-gate parentp->selfcalls == 0 && parentp->propself == 0 &&
3087c478bd9Sstevel@tonic-gate parentp -> propchild == 0)
3097c478bd9Sstevel@tonic-gate continue;
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate if (!parentp->printflag)
3127c478bd9Sstevel@tonic-gate continue;
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate /*
3157c478bd9Sstevel@tonic-gate * Do not print certain special symbols, like PRF_EXTSYM, etc.
3167c478bd9Sstevel@tonic-gate * even if zflag was on.
3177c478bd9Sstevel@tonic-gate */
3187c478bd9Sstevel@tonic-gate if (is_special_sym(parentp))
3197c478bd9Sstevel@tonic-gate continue;
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate if (parentp->name == 0 && parentp->cycleno != 0) {
3227c478bd9Sstevel@tonic-gate /*
3237c478bd9Sstevel@tonic-gate * cycle header
3247c478bd9Sstevel@tonic-gate */
3257c478bd9Sstevel@tonic-gate printcycle(parentp);
3267c478bd9Sstevel@tonic-gate printmembers(parentp);
3277c478bd9Sstevel@tonic-gate } else {
3287c478bd9Sstevel@tonic-gate printparents(parentp);
3297c478bd9Sstevel@tonic-gate gprofline(parentp);
3307c478bd9Sstevel@tonic-gate printchildren(parentp);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
33392ed1782Smike_s (void) printf("\n");
33492ed1782Smike_s (void) printf(
33592ed1782Smike_s "-----------------------------------------------\n");
33692ed1782Smike_s (void) printf("\n");
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate if (nflag) {
3397c478bd9Sstevel@tonic-gate --print_count;
3407c478bd9Sstevel@tonic-gate if (print_count == 0)
3417c478bd9Sstevel@tonic-gate count_flag = FALSE;
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate free(timesortnlp);
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate /*
3487c478bd9Sstevel@tonic-gate * sort by decreasing propagated time
3497c478bd9Sstevel@tonic-gate * if times are equal, but one is a cycle header,
3507c478bd9Sstevel@tonic-gate * say that's first (e.g. less, i.e. -1).
3517c478bd9Sstevel@tonic-gate * if one's name doesn't have an underscore and the other does,
3527c478bd9Sstevel@tonic-gate * say the one is first.
3537c478bd9Sstevel@tonic-gate * all else being equal, sort by names.
3547c478bd9Sstevel@tonic-gate */
3557c478bd9Sstevel@tonic-gate int
totalcmp(const void * arg1,const void * arg2)35692ed1782Smike_s totalcmp(const void *arg1, const void *arg2)
3577c478bd9Sstevel@tonic-gate {
35892ed1782Smike_s nltype **npp1 = (nltype **)arg1;
35992ed1782Smike_s nltype **npp2 = (nltype **)arg2;
3607c478bd9Sstevel@tonic-gate nltype *np1 = *npp1;
3617c478bd9Sstevel@tonic-gate nltype *np2 = *npp2;
3627c478bd9Sstevel@tonic-gate double diff;
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate diff = (np1->propself + np1->propchild) -
3657c478bd9Sstevel@tonic-gate (np2->propself + np2->propchild);
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate if (diff < 0.0)
3687c478bd9Sstevel@tonic-gate return (1);
3697c478bd9Sstevel@tonic-gate if (diff > 0.0)
3707c478bd9Sstevel@tonic-gate return (-1);
3717c478bd9Sstevel@tonic-gate if (np1->name == 0 && np1->cycleno != 0)
3727c478bd9Sstevel@tonic-gate return (-1);
3737c478bd9Sstevel@tonic-gate if (np2->name == 0 && np2->cycleno != 0)
3747c478bd9Sstevel@tonic-gate return (1);
3757c478bd9Sstevel@tonic-gate if (np1->name == 0)
3767c478bd9Sstevel@tonic-gate return (-1);
3777c478bd9Sstevel@tonic-gate if (np2->name == 0)
3787c478bd9Sstevel@tonic-gate return (1);
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate if (*(np1->name) != '_' && *(np2->name) == '_')
3817c478bd9Sstevel@tonic-gate return (-1);
3827c478bd9Sstevel@tonic-gate if (*(np1->name) == '_' && *(np2->name) != '_')
3837c478bd9Sstevel@tonic-gate return (1);
3847c478bd9Sstevel@tonic-gate if (np1->ncall > np2->ncall)
3857c478bd9Sstevel@tonic-gate return (-1);
3867c478bd9Sstevel@tonic-gate if (np1->ncall < np2->ncall)
3877c478bd9Sstevel@tonic-gate return (1);
3887c478bd9Sstevel@tonic-gate return (strcmp(np1->name, np2->name));
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate void
printparents(nltype * childp)3927c478bd9Sstevel@tonic-gate printparents(nltype *childp)
3937c478bd9Sstevel@tonic-gate {
3947c478bd9Sstevel@tonic-gate nltype *parentp;
3957c478bd9Sstevel@tonic-gate arctype *arcp;
3967c478bd9Sstevel@tonic-gate nltype *cycleheadp;
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate if (childp->cyclehead != 0)
3997c478bd9Sstevel@tonic-gate cycleheadp = childp -> cyclehead;
4007c478bd9Sstevel@tonic-gate else
4017c478bd9Sstevel@tonic-gate cycleheadp = childp;
4027c478bd9Sstevel@tonic-gate
4037c478bd9Sstevel@tonic-gate if (childp->parents == 0) {
40492ed1782Smike_s (void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s"
4057c478bd9Sstevel@tonic-gate " <spontaneous>\n", "", "", "", "", "", "");
4067c478bd9Sstevel@tonic-gate return;
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate sortparents(childp);
4107c478bd9Sstevel@tonic-gate
4117c478bd9Sstevel@tonic-gate for (arcp = childp->parents; arcp; arcp = arcp->arc_parentlist) {
4127c478bd9Sstevel@tonic-gate parentp = arcp -> arc_parentp;
4137c478bd9Sstevel@tonic-gate if (childp == parentp || (childp->cycleno != 0 &&
4147c478bd9Sstevel@tonic-gate parentp->cycleno == childp->cycleno)) {
4157c478bd9Sstevel@tonic-gate /*
4167c478bd9Sstevel@tonic-gate * selfcall or call among siblings
4177c478bd9Sstevel@tonic-gate */
41892ed1782Smike_s (void) printf(
41992ed1782Smike_s "%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
4207c478bd9Sstevel@tonic-gate "", "", "", "", arcp->arc_count, "");
4217c478bd9Sstevel@tonic-gate printname(parentp);
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate if (Cflag)
4247c478bd9Sstevel@tonic-gate print_demangled_name(54, parentp);
4257c478bd9Sstevel@tonic-gate
42692ed1782Smike_s (void) printf("\n");
4277c478bd9Sstevel@tonic-gate } else {
4287c478bd9Sstevel@tonic-gate /*
4297c478bd9Sstevel@tonic-gate * regular parent of child
4307c478bd9Sstevel@tonic-gate */
43192ed1782Smike_s (void) printf(
43292ed1782Smike_s "%6.6s %5.5s %7.2f %11.2f %7lld/%-7lld ", "",
4337c478bd9Sstevel@tonic-gate "", arcp->arc_time / hz, arcp->arc_childtime / hz,
4347c478bd9Sstevel@tonic-gate arcp->arc_count, cycleheadp->ncall);
4357c478bd9Sstevel@tonic-gate printname(parentp);
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate if (Cflag)
4387c478bd9Sstevel@tonic-gate print_demangled_name(54, parentp);
4397c478bd9Sstevel@tonic-gate
44092ed1782Smike_s (void) printf("\n");
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate void
printchildren(nltype * parentp)4467c478bd9Sstevel@tonic-gate printchildren(nltype *parentp)
4477c478bd9Sstevel@tonic-gate {
4487c478bd9Sstevel@tonic-gate nltype *childp;
4497c478bd9Sstevel@tonic-gate arctype *arcp;
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate sortchildren(parentp);
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate for (arcp = parentp->children; arcp; arcp = arcp->arc_childlist) {
4547c478bd9Sstevel@tonic-gate childp = arcp->arc_childp;
4557c478bd9Sstevel@tonic-gate if (childp == parentp || (childp->cycleno != 0 &&
4567c478bd9Sstevel@tonic-gate childp->cycleno == parentp->cycleno)) {
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate * self call or call to sibling
4597c478bd9Sstevel@tonic-gate */
46092ed1782Smike_s (void) printf(
46192ed1782Smike_s "%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
4627c478bd9Sstevel@tonic-gate "", "", "", "", arcp->arc_count, "");
4637c478bd9Sstevel@tonic-gate printname(childp);
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate if (Cflag)
4667c478bd9Sstevel@tonic-gate print_demangled_name(54, childp);
4677c478bd9Sstevel@tonic-gate
46892ed1782Smike_s (void) printf("\n");
4697c478bd9Sstevel@tonic-gate } else {
4707c478bd9Sstevel@tonic-gate /*
4717c478bd9Sstevel@tonic-gate * regular child of parent
4727c478bd9Sstevel@tonic-gate */
4737c478bd9Sstevel@tonic-gate if (childp->cyclehead)
47492ed1782Smike_s (void) printf("%6.6s %5.5s %7.2f %11.2f "
4757c478bd9Sstevel@tonic-gate "%7lld/%-7lld ", "", "",
4767c478bd9Sstevel@tonic-gate arcp->arc_time / hz,
4777c478bd9Sstevel@tonic-gate arcp->arc_childtime / hz, arcp->arc_count,
4787c478bd9Sstevel@tonic-gate childp->cyclehead->ncall);
4797c478bd9Sstevel@tonic-gate else
48092ed1782Smike_s (void) printf("%6.6s %5.5s %7.2f %11.2f "
4817c478bd9Sstevel@tonic-gate "%7lld %7.7s ",
4827c478bd9Sstevel@tonic-gate "", "", arcp->arc_time / hz,
4837c478bd9Sstevel@tonic-gate arcp->arc_childtime / hz, arcp->arc_count,
4847c478bd9Sstevel@tonic-gate "");
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate printname(childp);
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate if (Cflag)
4897c478bd9Sstevel@tonic-gate print_demangled_name(54, childp);
4907c478bd9Sstevel@tonic-gate
49192ed1782Smike_s (void) printf("\n");
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate void
printname(nltype * selfp)4977c478bd9Sstevel@tonic-gate printname(nltype *selfp)
4987c478bd9Sstevel@tonic-gate {
499*b9bd317cSab196087 const char *c;
5007c478bd9Sstevel@tonic-gate c = demangled_name(selfp);
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate if (selfp->name != 0) {
5037c478bd9Sstevel@tonic-gate if (!Cflag)
50492ed1782Smike_s (void) printf("%s", selfp->name);
5057c478bd9Sstevel@tonic-gate else
50692ed1782Smike_s (void) printf("%s", c);
5077c478bd9Sstevel@tonic-gate
5087c478bd9Sstevel@tonic-gate #ifdef DEBUG
5097c478bd9Sstevel@tonic-gate if (debug & DFNDEBUG)
51092ed1782Smike_s (void) printf("{%d} ", selfp->toporder);
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate if (debug & PROPDEBUG)
51392ed1782Smike_s (void) printf("%5.2f%% ", selfp->propfraction);
51492ed1782Smike_s #endif /* DEBUG */
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate if (selfp->cycleno != 0)
51892ed1782Smike_s (void) printf("\t<cycle %d>", selfp->cycleno);
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate if (selfp->index != 0) {
5217c478bd9Sstevel@tonic-gate if (selfp->printflag)
52292ed1782Smike_s (void) printf(" [%d]", selfp->index);
5237c478bd9Sstevel@tonic-gate else
52492ed1782Smike_s (void) printf(" (%d)", selfp->index);
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate void
print_demangled_name(int n,nltype * selfp)5297c478bd9Sstevel@tonic-gate print_demangled_name(int n, nltype *selfp)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate char *c;
5327c478bd9Sstevel@tonic-gate int i;
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate c = selfp->name;
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate if (strcmp(c, demangled_name(selfp)) == 0)
5377c478bd9Sstevel@tonic-gate return;
5387c478bd9Sstevel@tonic-gate else {
53992ed1782Smike_s (void) printf("\n");
5407c478bd9Sstevel@tonic-gate for (i = 1; i < n; i++)
54192ed1782Smike_s (void) printf(" ");
54292ed1782Smike_s (void) printf("[%s]", selfp->name);
5437c478bd9Sstevel@tonic-gate }
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate
5467c478bd9Sstevel@tonic-gate void
sortchildren(nltype * parentp)5477c478bd9Sstevel@tonic-gate sortchildren(nltype *parentp)
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate arctype *arcp;
5507c478bd9Sstevel@tonic-gate arctype *detachedp;
5517c478bd9Sstevel@tonic-gate arctype sorted;
5527c478bd9Sstevel@tonic-gate arctype *prevp;
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate /*
5557c478bd9Sstevel@tonic-gate * unlink children from parent,
5567c478bd9Sstevel@tonic-gate * then insertion sort back on to sorted's children.
5577c478bd9Sstevel@tonic-gate * *arcp the arc you have detached and are inserting.
5587c478bd9Sstevel@tonic-gate * *detachedp the rest of the arcs to be sorted.
5597c478bd9Sstevel@tonic-gate * sorted arc list onto which you insertion sort.
5607c478bd9Sstevel@tonic-gate * *prevp arc before the arc you are comparing.
5617c478bd9Sstevel@tonic-gate */
5627c478bd9Sstevel@tonic-gate sorted.arc_childlist = 0;
5637c478bd9Sstevel@tonic-gate
56492ed1782Smike_s /* LINTED: warning: assignment operator */
5657c478bd9Sstevel@tonic-gate for ((arcp = parentp->children) && (detachedp = arcp->arc_childlist);
5667c478bd9Sstevel@tonic-gate arcp;
56792ed1782Smike_s /* LINTED: warning: assignment operator */
5687c478bd9Sstevel@tonic-gate (arcp = detachedp) && (detachedp = detachedp->arc_childlist)) {
5697c478bd9Sstevel@tonic-gate /*
5707c478bd9Sstevel@tonic-gate * consider *arcp as disconnected
5717c478bd9Sstevel@tonic-gate * insert it into sorted
5727c478bd9Sstevel@tonic-gate */
5737c478bd9Sstevel@tonic-gate for (prevp = &sorted; prevp->arc_childlist;
5747c478bd9Sstevel@tonic-gate prevp = prevp->arc_childlist) {
5757c478bd9Sstevel@tonic-gate if (arccmp(arcp, prevp->arc_childlist) != LESSTHAN)
5767c478bd9Sstevel@tonic-gate break;
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate arcp->arc_childlist = prevp->arc_childlist;
5807c478bd9Sstevel@tonic-gate prevp->arc_childlist = arcp;
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate /*
5847c478bd9Sstevel@tonic-gate * reattach sorted children to parent
5857c478bd9Sstevel@tonic-gate */
5867c478bd9Sstevel@tonic-gate parentp->children = sorted.arc_childlist;
5877c478bd9Sstevel@tonic-gate }
5887c478bd9Sstevel@tonic-gate
5897c478bd9Sstevel@tonic-gate void
sortparents(nltype * childp)5907c478bd9Sstevel@tonic-gate sortparents(nltype *childp)
5917c478bd9Sstevel@tonic-gate {
5927c478bd9Sstevel@tonic-gate arctype *arcp;
5937c478bd9Sstevel@tonic-gate arctype *detachedp;
5947c478bd9Sstevel@tonic-gate arctype sorted;
5957c478bd9Sstevel@tonic-gate arctype *prevp;
5967c478bd9Sstevel@tonic-gate
5977c478bd9Sstevel@tonic-gate /*
5987c478bd9Sstevel@tonic-gate * unlink parents from child,
5997c478bd9Sstevel@tonic-gate * then insertion sort back on to sorted's parents.
6007c478bd9Sstevel@tonic-gate * *arcp the arc you have detached and are inserting.
6017c478bd9Sstevel@tonic-gate * *detachedp the rest of the arcs to be sorted.
6027c478bd9Sstevel@tonic-gate * sorted arc list onto which you insertion sort.
6037c478bd9Sstevel@tonic-gate * *prevp arc before the arc you are comparing.
6047c478bd9Sstevel@tonic-gate */
6057c478bd9Sstevel@tonic-gate sorted.arc_parentlist = 0;
6067c478bd9Sstevel@tonic-gate
60792ed1782Smike_s /* LINTED: warning: assignment operator */
6087c478bd9Sstevel@tonic-gate for ((arcp = childp->parents) && (detachedp = arcp->arc_parentlist);
6097c478bd9Sstevel@tonic-gate arcp;
61092ed1782Smike_s /* LINTED: warning: assignment operator */
6117c478bd9Sstevel@tonic-gate (arcp = detachedp) && (detachedp = detachedp->arc_parentlist)) {
6127c478bd9Sstevel@tonic-gate /*
6137c478bd9Sstevel@tonic-gate * consider *arcp as disconnected
6147c478bd9Sstevel@tonic-gate * insert it into sorted
6157c478bd9Sstevel@tonic-gate */
6167c478bd9Sstevel@tonic-gate for (prevp = &sorted; prevp->arc_parentlist;
6177c478bd9Sstevel@tonic-gate prevp = prevp->arc_parentlist) {
6187c478bd9Sstevel@tonic-gate if (arccmp(arcp, prevp->arc_parentlist) != GREATERTHAN)
6197c478bd9Sstevel@tonic-gate break;
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate arcp->arc_parentlist = prevp->arc_parentlist;
6227c478bd9Sstevel@tonic-gate prevp->arc_parentlist = arcp;
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate
6257c478bd9Sstevel@tonic-gate /*
6267c478bd9Sstevel@tonic-gate * reattach sorted arcs to child
6277c478bd9Sstevel@tonic-gate */
6287c478bd9Sstevel@tonic-gate childp->parents = sorted.arc_parentlist;
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate void
printcycle(nltype * cyclep)6327c478bd9Sstevel@tonic-gate printcycle(nltype *cyclep)
6337c478bd9Sstevel@tonic-gate {
6347c478bd9Sstevel@tonic-gate char kirkbuffer[BUFSIZ];
6357c478bd9Sstevel@tonic-gate
63692ed1782Smike_s (void) sprintf(kirkbuffer, "[%d]", cyclep->index);
63792ed1782Smike_s (void) printf("%-6.6s %5.1f %7.2f %11.2f %7lld", kirkbuffer,
6387c478bd9Sstevel@tonic-gate 100 * (cyclep->propself + cyclep->propchild) / printtime,
6397c478bd9Sstevel@tonic-gate cyclep -> propself / hz, cyclep -> propchild / hz,
6407c478bd9Sstevel@tonic-gate cyclep -> ncall);
6417c478bd9Sstevel@tonic-gate
6427c478bd9Sstevel@tonic-gate if (cyclep->selfcalls != 0)
64392ed1782Smike_s (void) printf("+%-7lld", cyclep->selfcalls);
6447c478bd9Sstevel@tonic-gate else
64592ed1782Smike_s (void) printf(" %7.7s", "");
6467c478bd9Sstevel@tonic-gate
64792ed1782Smike_s (void) printf(" <cycle %d as a whole>\t[%d]\n", cyclep->cycleno,
6487c478bd9Sstevel@tonic-gate cyclep->index);
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gate /*
6527c478bd9Sstevel@tonic-gate * print the members of a cycle
6537c478bd9Sstevel@tonic-gate */
6547c478bd9Sstevel@tonic-gate void
printmembers(nltype * cyclep)6557c478bd9Sstevel@tonic-gate printmembers(nltype *cyclep)
6567c478bd9Sstevel@tonic-gate {
6577c478bd9Sstevel@tonic-gate nltype *memberp;
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate sortmembers(cyclep);
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate for (memberp = cyclep->cnext; memberp; memberp = memberp->cnext) {
66292ed1782Smike_s (void) printf("%6.6s %5.5s %7.2f %11.2f %7lld", "", "",
6637c478bd9Sstevel@tonic-gate memberp->propself / hz, memberp->propchild / hz,
6647c478bd9Sstevel@tonic-gate memberp->ncall);
6657c478bd9Sstevel@tonic-gate
6667c478bd9Sstevel@tonic-gate if (memberp->selfcalls != 0)
66792ed1782Smike_s (void) printf("+%-7lld", memberp->selfcalls);
6687c478bd9Sstevel@tonic-gate else
66992ed1782Smike_s (void) printf(" %7.7s", "");
6707c478bd9Sstevel@tonic-gate
67192ed1782Smike_s (void) printf(" ");
6727c478bd9Sstevel@tonic-gate printname(memberp);
6737c478bd9Sstevel@tonic-gate if (Cflag)
6747c478bd9Sstevel@tonic-gate print_demangled_name(54, memberp);
67592ed1782Smike_s (void) printf("\n");
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate
6797c478bd9Sstevel@tonic-gate /*
6807c478bd9Sstevel@tonic-gate * sort members of a cycle
6817c478bd9Sstevel@tonic-gate */
6827c478bd9Sstevel@tonic-gate void
sortmembers(nltype * cyclep)6837c478bd9Sstevel@tonic-gate sortmembers(nltype *cyclep)
6847c478bd9Sstevel@tonic-gate {
6857c478bd9Sstevel@tonic-gate nltype *todo;
6867c478bd9Sstevel@tonic-gate nltype *doing;
6877c478bd9Sstevel@tonic-gate nltype *prev;
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate /*
6907c478bd9Sstevel@tonic-gate * detach cycle members from cyclehead,
6917c478bd9Sstevel@tonic-gate * and insertion sort them back on.
6927c478bd9Sstevel@tonic-gate */
6937c478bd9Sstevel@tonic-gate todo = cyclep->cnext;
6947c478bd9Sstevel@tonic-gate cyclep->cnext = 0;
6957c478bd9Sstevel@tonic-gate
69692ed1782Smike_s /* LINTED: warning: assignment operator */
6977c478bd9Sstevel@tonic-gate for ((doing = todo) && (todo = doing->cnext);
69892ed1782Smike_s doing;
69992ed1782Smike_s /* LINTED: warning: assignment operator */
70092ed1782Smike_s (doing = todo) && (todo = doing->cnext)) {
7017c478bd9Sstevel@tonic-gate for (prev = cyclep; prev->cnext; prev = prev->cnext) {
7027c478bd9Sstevel@tonic-gate if (membercmp(doing, prev->cnext) == GREATERTHAN)
7037c478bd9Sstevel@tonic-gate break;
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate doing->cnext = prev->cnext;
7067c478bd9Sstevel@tonic-gate prev->cnext = doing;
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate /*
7117c478bd9Sstevel@tonic-gate * major sort is on propself + propchild,
7127c478bd9Sstevel@tonic-gate * next is sort on ncalls + selfcalls.
7137c478bd9Sstevel@tonic-gate */
7147c478bd9Sstevel@tonic-gate int
membercmp(nltype * this,nltype * that)7157c478bd9Sstevel@tonic-gate membercmp(nltype *this, nltype *that)
7167c478bd9Sstevel@tonic-gate {
7177c478bd9Sstevel@tonic-gate double thistime = this->propself + this->propchild;
7187c478bd9Sstevel@tonic-gate double thattime = that->propself + that->propchild;
7197c478bd9Sstevel@tonic-gate actype thiscalls = this->ncall + this->selfcalls;
7207c478bd9Sstevel@tonic-gate actype thatcalls = that->ncall + that->selfcalls;
7217c478bd9Sstevel@tonic-gate
7227c478bd9Sstevel@tonic-gate if (thistime > thattime)
7237c478bd9Sstevel@tonic-gate return (GREATERTHAN);
7247c478bd9Sstevel@tonic-gate
7257c478bd9Sstevel@tonic-gate if (thistime < thattime)
7267c478bd9Sstevel@tonic-gate return (LESSTHAN);
7277c478bd9Sstevel@tonic-gate
7287c478bd9Sstevel@tonic-gate if (thiscalls > thatcalls)
7297c478bd9Sstevel@tonic-gate return (GREATERTHAN);
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate if (thiscalls < thatcalls)
7327c478bd9Sstevel@tonic-gate return (LESSTHAN);
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate return (EQUALTO);
7357c478bd9Sstevel@tonic-gate }
7367c478bd9Sstevel@tonic-gate
7377c478bd9Sstevel@tonic-gate /*
7387c478bd9Sstevel@tonic-gate * compare two arcs to/from the same child/parent.
7397c478bd9Sstevel@tonic-gate * - if one arc is a self arc, it's least.
7407c478bd9Sstevel@tonic-gate * - if one arc is within a cycle, it's less than.
7417c478bd9Sstevel@tonic-gate * - if both arcs are within a cycle, compare arc counts.
7427c478bd9Sstevel@tonic-gate * - if neither arc is within a cycle, compare with
7437c478bd9Sstevel@tonic-gate * arc_time + arc_childtime as major key
7447c478bd9Sstevel@tonic-gate * arc count as minor key
7457c478bd9Sstevel@tonic-gate */
7467c478bd9Sstevel@tonic-gate int
arccmp(arctype * thisp,arctype * thatp)7477c478bd9Sstevel@tonic-gate arccmp(arctype *thisp, arctype *thatp)
7487c478bd9Sstevel@tonic-gate {
7497c478bd9Sstevel@tonic-gate nltype *thisparentp = thisp->arc_parentp;
7507c478bd9Sstevel@tonic-gate nltype *thischildp = thisp->arc_childp;
7517c478bd9Sstevel@tonic-gate nltype *thatparentp = thatp->arc_parentp;
7527c478bd9Sstevel@tonic-gate nltype *thatchildp = thatp->arc_childp;
7537c478bd9Sstevel@tonic-gate double thistime;
7547c478bd9Sstevel@tonic-gate double thattime;
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate #ifdef DEBUG
7577c478bd9Sstevel@tonic-gate if (debug & TIMEDEBUG) {
75892ed1782Smike_s (void) printf("[arccmp] ");
7597c478bd9Sstevel@tonic-gate printname(thisparentp);
76092ed1782Smike_s (void) printf(" calls ");
7617c478bd9Sstevel@tonic-gate printname(thischildp);
76292ed1782Smike_s (void) printf(" %f + %f %lld/%lld\n", thisp->arc_time,
7637c478bd9Sstevel@tonic-gate thisp->arc_childtime, thisp->arc_count,
7647c478bd9Sstevel@tonic-gate thischildp->ncall);
76592ed1782Smike_s (void) printf("[arccmp] ");
7667c478bd9Sstevel@tonic-gate printname(thatparentp);
76792ed1782Smike_s (void) printf(" calls ");
7687c478bd9Sstevel@tonic-gate printname(thatchildp);
76992ed1782Smike_s (void) printf(" %f + %f %lld/%lld\n", thatp->arc_time,
7707c478bd9Sstevel@tonic-gate thatp->arc_childtime, thatp->arc_count,
7717c478bd9Sstevel@tonic-gate thatchildp->ncall);
77292ed1782Smike_s (void) printf("\n");
7737c478bd9Sstevel@tonic-gate }
77492ed1782Smike_s #endif /* DEBUG */
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate if (thisparentp == thischildp) {
7777c478bd9Sstevel@tonic-gate /*
7787c478bd9Sstevel@tonic-gate * this is a self call
7797c478bd9Sstevel@tonic-gate */
7807c478bd9Sstevel@tonic-gate return (LESSTHAN);
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate if (thatparentp == thatchildp) {
7847c478bd9Sstevel@tonic-gate /*
7857c478bd9Sstevel@tonic-gate * that is a self call
7867c478bd9Sstevel@tonic-gate */
7877c478bd9Sstevel@tonic-gate return (GREATERTHAN);
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate if (thisparentp->cycleno != 0 && thischildp->cycleno != 0 &&
7917c478bd9Sstevel@tonic-gate thisparentp->cycleno == thischildp->cycleno) {
7927c478bd9Sstevel@tonic-gate /*
7937c478bd9Sstevel@tonic-gate * this is a call within a cycle
7947c478bd9Sstevel@tonic-gate */
7957c478bd9Sstevel@tonic-gate if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
7967c478bd9Sstevel@tonic-gate thatparentp->cycleno == thatchildp->cycleno) {
7977c478bd9Sstevel@tonic-gate /*
7987c478bd9Sstevel@tonic-gate * that is a call within the cycle, too
7997c478bd9Sstevel@tonic-gate */
8007c478bd9Sstevel@tonic-gate if (thisp->arc_count < thatp->arc_count)
8017c478bd9Sstevel@tonic-gate return (LESSTHAN);
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate if (thisp->arc_count > thatp->arc_count)
8047c478bd9Sstevel@tonic-gate return (GREATERTHAN);
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gate return (EQUALTO);
8077c478bd9Sstevel@tonic-gate } else {
8087c478bd9Sstevel@tonic-gate /*
8097c478bd9Sstevel@tonic-gate * that isn't a call within the cycle
8107c478bd9Sstevel@tonic-gate */
8117c478bd9Sstevel@tonic-gate return (LESSTHAN);
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate } else {
8147c478bd9Sstevel@tonic-gate /*
8157c478bd9Sstevel@tonic-gate * this isn't a call within a cycle
8167c478bd9Sstevel@tonic-gate */
8177c478bd9Sstevel@tonic-gate if (thatparentp->cycleno != 0 && thatchildp->cycleno != 0 &&
8187c478bd9Sstevel@tonic-gate thatparentp->cycleno == thatchildp->cycleno) {
8197c478bd9Sstevel@tonic-gate /*
8207c478bd9Sstevel@tonic-gate * that is a call within a cycle
8217c478bd9Sstevel@tonic-gate */
8227c478bd9Sstevel@tonic-gate return (GREATERTHAN);
8237c478bd9Sstevel@tonic-gate } else {
8247c478bd9Sstevel@tonic-gate /*
8257c478bd9Sstevel@tonic-gate * neither is a call within a cycle
8267c478bd9Sstevel@tonic-gate */
8277c478bd9Sstevel@tonic-gate thistime = thisp->arc_time + thisp->arc_childtime;
8287c478bd9Sstevel@tonic-gate thattime = thatp->arc_time + thatp->arc_childtime;
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate if (thistime < thattime)
8317c478bd9Sstevel@tonic-gate return (LESSTHAN);
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate if (thistime > thattime)
8347c478bd9Sstevel@tonic-gate return (GREATERTHAN);
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate if (thisp->arc_count < thatp->arc_count)
8377c478bd9Sstevel@tonic-gate return (LESSTHAN);
8387c478bd9Sstevel@tonic-gate
8397c478bd9Sstevel@tonic-gate if (thisp->arc_count > thatp->arc_count)
8407c478bd9Sstevel@tonic-gate return (GREATERTHAN);
8417c478bd9Sstevel@tonic-gate
8427c478bd9Sstevel@tonic-gate return (EQUALTO);
8437c478bd9Sstevel@tonic-gate }
8447c478bd9Sstevel@tonic-gate }
8457c478bd9Sstevel@tonic-gate }
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate void
printblurb(char * blurbname)8487c478bd9Sstevel@tonic-gate printblurb(char *blurbname)
8497c478bd9Sstevel@tonic-gate {
8507c478bd9Sstevel@tonic-gate FILE *blurbfile;
8517c478bd9Sstevel@tonic-gate int input;
8527c478bd9Sstevel@tonic-gate
85367298654Sdamico blurbfile = fopen(blurbname, "r");
8547c478bd9Sstevel@tonic-gate if (blurbfile == NULL) {
85567298654Sdamico perror(blurbname);
8567c478bd9Sstevel@tonic-gate return;
8577c478bd9Sstevel@tonic-gate }
8587c478bd9Sstevel@tonic-gate
8597c478bd9Sstevel@tonic-gate while ((input = getc(blurbfile)) != EOF)
86092ed1782Smike_s (void) putchar(input);
8617c478bd9Sstevel@tonic-gate
86292ed1782Smike_s (void) fclose(blurbfile);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate char *s1, *s2;
8667c478bd9Sstevel@tonic-gate
86792ed1782Smike_s static int
namecmp(const void * arg1,const void * arg2)86892ed1782Smike_s namecmp(const void *arg1, const void *arg2)
8697c478bd9Sstevel@tonic-gate {
87092ed1782Smike_s nltype **npp1 = (nltype **)arg1;
87192ed1782Smike_s nltype **npp2 = (nltype **)arg2;
87292ed1782Smike_s
8737c478bd9Sstevel@tonic-gate if (!Cflag)
8747c478bd9Sstevel@tonic-gate return (strcmp((*npp1)->name, (*npp2)->name));
8757c478bd9Sstevel@tonic-gate else {
8767c478bd9Sstevel@tonic-gate striped_name(s1, npp1);
8777c478bd9Sstevel@tonic-gate striped_name(s2, npp2);
8787c478bd9Sstevel@tonic-gate return (strcmp(s1, s2));
8797c478bd9Sstevel@tonic-gate }
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate void
striped_name(char * s,nltype ** npp)8837c478bd9Sstevel@tonic-gate striped_name(char *s, nltype **npp)
8847c478bd9Sstevel@tonic-gate {
885*b9bd317cSab196087 const char *d;
886*b9bd317cSab196087 char *c;
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate c = (char *)s;
8897c478bd9Sstevel@tonic-gate d = demangled_name(*npp);
8907c478bd9Sstevel@tonic-gate
8917c478bd9Sstevel@tonic-gate while ((*d != '(') && (*d != '\0')) {
8927c478bd9Sstevel@tonic-gate if (*d != ':')
8937c478bd9Sstevel@tonic-gate *c++ = *d++;
8947c478bd9Sstevel@tonic-gate else
8957c478bd9Sstevel@tonic-gate d++;
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate *c = '\0';
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate
9007c478bd9Sstevel@tonic-gate /*
9017c478bd9Sstevel@tonic-gate * Checks if the current symbol name is the same as its neighbour and
9027c478bd9Sstevel@tonic-gate * returns TRUE if it is.
9037c478bd9Sstevel@tonic-gate */
9047c478bd9Sstevel@tonic-gate static bool
does_clash(nltype ** nlp,int ndx,int nnames)9057c478bd9Sstevel@tonic-gate does_clash(nltype **nlp, int ndx, int nnames)
9067c478bd9Sstevel@tonic-gate {
9077c478bd9Sstevel@tonic-gate /*
9087c478bd9Sstevel@tonic-gate * same as previous (if there's one) ?
9097c478bd9Sstevel@tonic-gate */
9107c478bd9Sstevel@tonic-gate if (ndx && (strcmp(nlp[ndx]->name, nlp[ndx-1]->name) == 0))
9117c478bd9Sstevel@tonic-gate return (TRUE);
9127c478bd9Sstevel@tonic-gate
9137c478bd9Sstevel@tonic-gate /*
9147c478bd9Sstevel@tonic-gate * same as next (if there's one) ?
9157c478bd9Sstevel@tonic-gate */
9167c478bd9Sstevel@tonic-gate if ((ndx < (nnames - 1)) &&
9177c478bd9Sstevel@tonic-gate (strcmp(nlp[ndx]->name, nlp[ndx+1]->name) == 0)) {
9187c478bd9Sstevel@tonic-gate return (TRUE);
9197c478bd9Sstevel@tonic-gate }
9207c478bd9Sstevel@tonic-gate
9217c478bd9Sstevel@tonic-gate return (FALSE);
9227c478bd9Sstevel@tonic-gate }
9237c478bd9Sstevel@tonic-gate
9247c478bd9Sstevel@tonic-gate void
printmodules()9257c478bd9Sstevel@tonic-gate printmodules()
9267c478bd9Sstevel@tonic-gate {
9277c478bd9Sstevel@tonic-gate mod_info_t *mi;
9287c478bd9Sstevel@tonic-gate
92992ed1782Smike_s (void) printf("\f\nObject modules\n\n");
9307c478bd9Sstevel@tonic-gate for (mi = &modules; mi; mi = mi->next)
93192ed1782Smike_s (void) printf(" %d: %s\n", mi->id, mi->name);
9327c478bd9Sstevel@tonic-gate }
9337c478bd9Sstevel@tonic-gate
9347c478bd9Sstevel@tonic-gate #define IDFMT(id) ((id) < 10 ? 1 : 2)
9357c478bd9Sstevel@tonic-gate #define NMFMT(id) ((id) < 10 ? 17 : 16)
9367c478bd9Sstevel@tonic-gate
9377c478bd9Sstevel@tonic-gate void
printindex()9387c478bd9Sstevel@tonic-gate printindex()
9397c478bd9Sstevel@tonic-gate {
9407c478bd9Sstevel@tonic-gate nltype **namesortnlp;
9417c478bd9Sstevel@tonic-gate nltype *nlp;
9427c478bd9Sstevel@tonic-gate int index, nnames, todo, i, j;
9437c478bd9Sstevel@tonic-gate char peterbuffer[BUFSIZ];
9447c478bd9Sstevel@tonic-gate mod_info_t *mi;
9457c478bd9Sstevel@tonic-gate
9467c478bd9Sstevel@tonic-gate /*
9477c478bd9Sstevel@tonic-gate * Now, sort regular function name alphabetically
9487c478bd9Sstevel@tonic-gate * to create an index.
9497c478bd9Sstevel@tonic-gate */
9507c478bd9Sstevel@tonic-gate namesortnlp = calloc(total_names + ncycle, sizeof (nltype *));
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate if (namesortnlp == NULL)
95392ed1782Smike_s (void) fprintf(stderr, "%s: ran out of memory for sorting\n",
95492ed1782Smike_s whoami);
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate nnames = 0;
9577c478bd9Sstevel@tonic-gate for (mi = &modules; mi; mi = mi->next) {
9587c478bd9Sstevel@tonic-gate for (index = 0; index < mi->nname; index++) {
9597c478bd9Sstevel@tonic-gate if (zflag == 0 && (mi->nl[index]).ncall == 0 &&
9607c478bd9Sstevel@tonic-gate (mi->nl[index]).time == 0) {
9617c478bd9Sstevel@tonic-gate continue;
9627c478bd9Sstevel@tonic-gate }
9637c478bd9Sstevel@tonic-gate
9647c478bd9Sstevel@tonic-gate /*
9657c478bd9Sstevel@tonic-gate * Do not print certain special symbols, like
9667c478bd9Sstevel@tonic-gate * PRF_EXTSYM, etc. even if zflag was on.
9677c478bd9Sstevel@tonic-gate */
9687c478bd9Sstevel@tonic-gate if (is_special_sym(&(mi->nl[index])))
9697c478bd9Sstevel@tonic-gate continue;
9707c478bd9Sstevel@tonic-gate
9717c478bd9Sstevel@tonic-gate namesortnlp[nnames++] = &(mi->nl[index]);
9727c478bd9Sstevel@tonic-gate }
9737c478bd9Sstevel@tonic-gate }
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate if (Cflag) {
9767c478bd9Sstevel@tonic-gate s1 = malloc(500 * sizeof (char));
9777c478bd9Sstevel@tonic-gate s2 = malloc(500 * sizeof (char));
9787c478bd9Sstevel@tonic-gate }
9797c478bd9Sstevel@tonic-gate
98092ed1782Smike_s qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
9817c478bd9Sstevel@tonic-gate
9827c478bd9Sstevel@tonic-gate for (index = 1, todo = nnames; index <= ncycle; index++)
9837c478bd9Sstevel@tonic-gate namesortnlp[todo++] = &cyclenl[index];
9847c478bd9Sstevel@tonic-gate
98592ed1782Smike_s (void) printf("\f\nIndex by function name\n\n");
9867c478bd9Sstevel@tonic-gate
9877c478bd9Sstevel@tonic-gate if (!Cflag)
9887c478bd9Sstevel@tonic-gate index = (todo + 2) / 3;
9897c478bd9Sstevel@tonic-gate else
9907c478bd9Sstevel@tonic-gate index = todo;
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate for (i = 0; i < index; i++) {
9937c478bd9Sstevel@tonic-gate if (!Cflag) {
9947c478bd9Sstevel@tonic-gate for (j = i; j < todo; j += index) {
9957c478bd9Sstevel@tonic-gate nlp = namesortnlp[j];
9967c478bd9Sstevel@tonic-gate
9977c478bd9Sstevel@tonic-gate if (nlp->printflag) {
99892ed1782Smike_s (void) sprintf(peterbuffer,
9997c478bd9Sstevel@tonic-gate "[%d]", nlp->index);
10007c478bd9Sstevel@tonic-gate } else {
100192ed1782Smike_s (void) sprintf(peterbuffer,
10027c478bd9Sstevel@tonic-gate "(%d)", nlp->index);
10037c478bd9Sstevel@tonic-gate }
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate if (j < nnames) {
10067c478bd9Sstevel@tonic-gate if (does_clash(namesortnlp,
10077c478bd9Sstevel@tonic-gate j, nnames)) {
100892ed1782Smike_s (void) printf(
100992ed1782Smike_s "%6.6s %*d:%-*.*s",
10107c478bd9Sstevel@tonic-gate peterbuffer,
10117c478bd9Sstevel@tonic-gate IDFMT(nlp->module->id),
10127c478bd9Sstevel@tonic-gate nlp->module->id,
10137c478bd9Sstevel@tonic-gate NMFMT(nlp->module->id),
10147c478bd9Sstevel@tonic-gate NMFMT(nlp->module->id),
10157c478bd9Sstevel@tonic-gate nlp->name);
10167c478bd9Sstevel@tonic-gate } else {
101792ed1782Smike_s (void) printf("%6.6s %-19.19s",
10187c478bd9Sstevel@tonic-gate peterbuffer, nlp->name);
10197c478bd9Sstevel@tonic-gate }
10207c478bd9Sstevel@tonic-gate } else {
102192ed1782Smike_s (void) printf("%6.6s ", peterbuffer);
102292ed1782Smike_s (void) sprintf(peterbuffer,
10237c478bd9Sstevel@tonic-gate "<cycle %d>", nlp->cycleno);
102492ed1782Smike_s (void) printf("%-19.19s", peterbuffer);
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate }
10277c478bd9Sstevel@tonic-gate } else {
10287c478bd9Sstevel@tonic-gate nlp = namesortnlp[i];
10297c478bd9Sstevel@tonic-gate
10307c478bd9Sstevel@tonic-gate if (nlp->printflag)
103192ed1782Smike_s (void) sprintf(peterbuffer, "[%d]", nlp->index);
10327c478bd9Sstevel@tonic-gate else
103392ed1782Smike_s (void) sprintf(peterbuffer, "(%d)", nlp->index);
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate if (i < nnames) {
1036*b9bd317cSab196087 const char *d = demangled_name(nlp);
10377c478bd9Sstevel@tonic-gate
10387c478bd9Sstevel@tonic-gate if (does_clash(namesortnlp, i, nnames)) {
103992ed1782Smike_s (void) printf("%6.6s %d:%s\n",
104092ed1782Smike_s peterbuffer, nlp->module->id, d);
10417c478bd9Sstevel@tonic-gate } else
104292ed1782Smike_s (void) printf("%6.6s %s\n", peterbuffer,
104392ed1782Smike_s d);
10447c478bd9Sstevel@tonic-gate
10457c478bd9Sstevel@tonic-gate if (d != nlp->name)
104692ed1782Smike_s (void) printf("%6.6s [%s]", "",
104792ed1782Smike_s nlp->name);
10487c478bd9Sstevel@tonic-gate } else {
104992ed1782Smike_s (void) printf("%6.6s ", peterbuffer);
105092ed1782Smike_s (void) sprintf(peterbuffer, "<cycle %d>",
10517c478bd9Sstevel@tonic-gate nlp->cycleno);
105292ed1782Smike_s (void) printf("%-33.33s", peterbuffer);
10537c478bd9Sstevel@tonic-gate }
10547c478bd9Sstevel@tonic-gate }
105592ed1782Smike_s (void) printf("\n");
10567c478bd9Sstevel@tonic-gate }
10577c478bd9Sstevel@tonic-gate free(namesortnlp);
10587c478bd9Sstevel@tonic-gate }
1059