/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "conv.h"
#include "gprof.h"
void print_demangled_name(int, nltype *);
void striped_name(char *, nltype **);
extern long hz;
/*
* Symbols that must never be printed, no matter what.
*/
char *splsym[] = {
};
const char *
{
if (!Cflag)
}
void
printprof(void)
{
int i, index;
actime = 0.0;
(void) printf("\f\n");
/*
* Sort the symbol table in by time
*/
"[printprof] ran out of memory for time sorting\n");
}
index = 0;
}
if (nflag) {
if (--print_count == 0)
print_flag = FALSE;
}
}
actime = 0.0;
}
int
{
double timediff;
long calldiff;
if (timediff > 0.0)
return (1);
if (timediff < 0.0)
return (-1);
if (calldiff > 0)
return (1);
if (calldiff < 0)
return (-1);
}
/*
* header for flatprofline
*/
void
{
if (bflag)
if (old_style) {
(void) printf(
"\ngranularity: each sample hit covers %d byte(s)",
if (totime > 0.0) {
(void) printf(" for %.2f%% of %.2f seconds\n\n",
} else {
(void) printf(" no time accumulated\n\n");
/*
* this doesn't hurt since all the numerators will
* be zero.
*/
totime = 1.0;
}
}
(void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
"% ", "cumulative", "self ", "", "self ", "total ", "");
(void) printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
"time", "seconds ", "seconds", "calls",
}
void
{
return;
/*
* Do not print certain special symbols, like PRF_EXTSYM, etc.
* even if zflag was on.
*/
if (is_special_sym(np))
return;
(void) printf("%5.1f %10.2f %8.2f",
} else {
if (!Cflag)
else
}
if (Cflag)
(void) printf("\n");
}
void
{
if (bflag)
if (old_style) {
(void) printf(
"\ngranularity: each sample hit covers %d byte(s)",
if (printtime > 0.0) {
(void) printf(" for %.2f%% of %.2f seconds\n\n",
} else {
(void) printf(" no time propagated\n\n");
/*
* this doesn't hurt, since all the numerators
* will be 0.0
*/
printtime = 1.0;
}
} else {
(void) printf(
"\ngranularity: each pc-hit is considered 1 tick");
if (hz != 1) {
(void) printf(" (@ %4.3f seconds per tick)",
(double)1.0 / hz);
}
(void) puts("\n\n");
}
(void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
"", "", "", "", "called", "total", "parents");
(void) printf("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
"index", "%time", "self", "descendents",
"called", "self", "name", "index");
(void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
"", "", "", "", "called", "total", "children");
(void) printf("\n");
}
void
{
else
} else {
}
if (Cflag)
(void) printf("\n");
}
static bool
{
int i;
return (FALSE);
for (i = 0; splsym[i]; i++)
return (TRUE);
return (FALSE);
}
void
{
int index;
/*
* Print out the structured profiling list
*/
gprofheader();
continue;
continue;
/*
* Do not print certain special symbols, like PRF_EXTSYM, etc.
* even if zflag was on.
*/
if (is_special_sym(parentp))
continue;
/*
* cycle header
*/
} else {
}
(void) printf("\n");
(void) printf(
"-----------------------------------------------\n");
(void) printf("\n");
if (nflag) {
--print_count;
if (print_count == 0)
count_flag = FALSE;
}
}
}
/*
* sort by decreasing propagated time
* if times are equal, but one is a cycle header,
* say that's first (e.g. less, i.e. -1).
* if one's name doesn't have an underscore and the other does,
* say the one is first.
* all else being equal, sort by names.
*/
int
{
double diff;
if (diff < 0.0)
return (1);
if (diff > 0.0)
return (-1);
return (-1);
return (1);
return (-1);
return (1);
return (-1);
return (1);
return (-1);
return (1);
}
void
{
else
cycleheadp = childp;
(void) printf("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s"
" <spontaneous>\n", "", "", "", "", "", "");
return;
}
/*
* selfcall or call among siblings
*/
(void) printf(
"%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
if (Cflag)
(void) printf("\n");
} else {
/*
* regular parent of child
*/
(void) printf(
"%6.6s %5.5s %7.2f %11.2f %7lld/%-7lld ", "",
if (Cflag)
(void) printf("\n");
}
}
}
void
{
/*
* self call or call to sibling
*/
(void) printf(
"%6.6s %5.5s %7.7s %11.11s %7lld %7.7s ",
if (Cflag)
(void) printf("\n");
} else {
/*
* regular child of parent
*/
(void) printf("%6.6s %5.5s %7.2f %11.2f "
"%7lld/%-7lld ", "", "",
else
(void) printf("%6.6s %5.5s %7.2f %11.2f "
"%7lld %7.7s ",
"");
if (Cflag)
(void) printf("\n");
}
}
}
void
{
const char *c;
c = demangled_name(selfp);
if (!Cflag)
else
(void) printf("%s", c);
#ifdef DEBUG
#endif /* DEBUG */
}
else
}
}
void
{
char *c;
int i;
return;
else {
(void) printf("\n");
for (i = 1; i < n; i++)
(void) printf(" ");
}
}
void
{
/*
* unlink children from parent,
* then insertion sort back on to sorted's children.
* *arcp the arc you have detached and are inserting.
* *detachedp the rest of the arcs to be sorted.
* sorted arc list onto which you insertion sort.
* *prevp arc before the arc you are comparing.
*/
sorted.arc_childlist = 0;
/* LINTED: warning: assignment operator */
arcp;
/* LINTED: warning: assignment operator */
/*
* consider *arcp as disconnected
* insert it into sorted
*/
break;
}
}
/*
* reattach sorted children to parent
*/
}
void
{
/*
* unlink parents from child,
* then insertion sort back on to sorted's parents.
* *arcp the arc you have detached and are inserting.
* *detachedp the rest of the arcs to be sorted.
* sorted arc list onto which you insertion sort.
* *prevp arc before the arc you are comparing.
*/
sorted.arc_parentlist = 0;
/* LINTED: warning: assignment operator */
arcp;
/* LINTED: warning: assignment operator */
/*
* consider *arcp as disconnected
* insert it into sorted
*/
break;
}
}
/*
* reattach sorted arcs to child
*/
}
void
{
else
}
/*
* print the members of a cycle
*/
void
{
else
(void) printf(" ");
if (Cflag)
(void) printf("\n");
}
}
/*
* sort members of a cycle
*/
void
{
/*
* detach cycle members from cyclehead,
* and insertion sort them back on.
*/
/* LINTED: warning: assignment operator */
/* LINTED: warning: assignment operator */
break;
}
}
}
/*
* major sort is on propself + propchild,
* next is sort on ncalls + selfcalls.
*/
int
{
return (GREATERTHAN);
return (LESSTHAN);
return (GREATERTHAN);
return (LESSTHAN);
return (EQUALTO);
}
/*
* - if one arc is a self arc, it's least.
* - if one arc is within a cycle, it's less than.
* - if both arcs are within a cycle, compare arc counts.
* - if neither arc is within a cycle, compare with
* arc_time + arc_childtime as major key
* arc count as minor key
*/
int
{
double thistime;
double thattime;
#ifdef DEBUG
(void) printf("[arccmp] ");
(void) printf(" calls ");
thischildp->ncall);
(void) printf("[arccmp] ");
(void) printf(" calls ");
thatchildp->ncall);
(void) printf("\n");
}
#endif /* DEBUG */
if (thisparentp == thischildp) {
/*
* this is a self call
*/
return (LESSTHAN);
}
if (thatparentp == thatchildp) {
/*
* that is a self call
*/
return (GREATERTHAN);
}
/*
* this is a call within a cycle
*/
/*
* that is a call within the cycle, too
*/
return (LESSTHAN);
return (GREATERTHAN);
return (EQUALTO);
} else {
/*
* that isn't a call within the cycle
*/
return (LESSTHAN);
}
} else {
/*
* this isn't a call within a cycle
*/
/*
* that is a call within a cycle
*/
return (GREATERTHAN);
} else {
/*
* neither is a call within a cycle
*/
return (LESSTHAN);
return (GREATERTHAN);
return (LESSTHAN);
return (GREATERTHAN);
return (EQUALTO);
}
}
}
void
{
int input;
return;
}
}
static int
{
if (!Cflag)
else {
}
}
void
{
const char *d;
char *c;
c = (char *)s;
d = demangled_name(*npp);
while ((*d != '(') && (*d != '\0')) {
if (*d != ':')
*c++ = *d++;
else
d++;
}
*c = '\0';
}
/*
* Checks if the current symbol name is the same as its neighbour and
* returns TRUE if it is.
*/
static bool
{
/*
* same as previous (if there's one) ?
*/
return (TRUE);
/*
* same as next (if there's one) ?
*/
return (TRUE);
}
return (FALSE);
}
void
{
(void) printf("\f\nObject modules\n\n");
}
void
{
/*
* Now, sort regular function name alphabetically
* to create an index.
*/
if (namesortnlp == NULL)
whoami);
nnames = 0;
continue;
}
/*
* Do not print certain special symbols, like
* PRF_EXTSYM, etc. even if zflag was on.
*/
continue;
}
}
if (Cflag) {
}
(void) printf("\f\nIndex by function name\n\n");
if (!Cflag)
else
for (i = 0; i < index; i++) {
if (!Cflag) {
nlp = namesortnlp[j];
(void) sprintf(peterbuffer,
} else {
(void) sprintf(peterbuffer,
}
if (j < nnames) {
if (does_clash(namesortnlp,
j, nnames)) {
(void) printf(
"%6.6s %*d:%-*.*s",
} else {
(void) printf("%6.6s %-19.19s",
}
} else {
(void) sprintf(peterbuffer,
}
}
} else {
nlp = namesortnlp[i];
else
if (i < nnames) {
const char *d = demangled_name(nlp);
(void) printf("%6.6s %d:%s\n",
} else
d);
} else {
}
}
(void) printf("\n");
}
}