Print this page
6375 Add native name demangling support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
*** 20,42 ****
*/
/*
* 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 <sys/param.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.
--- 20,43 ----
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Jason King
+ * Copyright 2018, Joyent, Inc.
*/
#include <ctype.h>
#include <string.h>
#include <sys/param.h>
#include <stdlib.h>
#include "conv.h"
#include "gprof.h"
void print_demangled_name(int, nltype *);
! static void stripped_name(char **, size_t *, nltype **);
extern long hz;
/*
* Symbols that must never be printed, no matter what.
*** 498,510 ****
{
const char *c;
c = demangled_name(selfp);
if (selfp->name != 0) {
- if (!Cflag)
- (void) printf("%s", selfp->name);
- else
(void) printf("%s", c);
#ifdef DEBUG
if (debug & DFNDEBUG)
(void) printf("{%d} ", selfp->toporder);
--- 499,508 ----
*** 521,548 ****
if (selfp->printflag)
(void) printf(" [%d]", selfp->index);
else
(void) printf(" (%d)", selfp->index);
}
}
void
print_demangled_name(int n, nltype *selfp)
{
! char *c;
int i;
! c = selfp->name;
!
! if (strcmp(c, demangled_name(selfp)) == 0)
return;
! else {
(void) printf("\n");
for (i = 1; i < n; i++)
(void) printf(" ");
(void) printf("[%s]", selfp->name);
! }
}
void
sortchildren(nltype *parentp)
{
--- 519,548 ----
if (selfp->printflag)
(void) printf(" [%d]", selfp->index);
else
(void) printf(" (%d)", selfp->index);
}
+
+ if (c != selfp->name)
+ free((void *)c);
}
void
print_demangled_name(int n, nltype *selfp)
{
! char *c = (char *)demangled_name(selfp);
int i;
! if (c == selfp->name)
return;
!
(void) printf("\n");
for (i = 1; i < n; i++)
(void) printf(" ");
(void) printf("[%s]", selfp->name);
!
! free(c);
}
void
sortchildren(nltype *parentp)
{
*** 860,902 ****
(void) putchar(input);
(void) fclose(blurbfile);
}
- char *s1, *s2;
-
static int
namecmp(const void *arg1, const void *arg2)
{
nltype **npp1 = (nltype **)arg1;
nltype **npp2 = (nltype **)arg2;
if (!Cflag)
return (strcmp((*npp1)->name, (*npp2)->name));
else {
! striped_name(s1, npp1);
! striped_name(s2, npp2);
return (strcmp(s1, s2));
}
}
! void
! striped_name(char *s, nltype **npp)
{
! 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.
--- 860,933 ----
(void) putchar(input);
(void) fclose(blurbfile);
}
static int
namecmp(const void *arg1, const void *arg2)
{
nltype **npp1 = (nltype **)arg1;
nltype **npp2 = (nltype **)arg2;
if (!Cflag)
return (strcmp((*npp1)->name, (*npp2)->name));
else {
! static char *s1 = NULL, *s2 = NULL;
! static size_t s1len = 0, s2len = 0;
!
! stripped_name(&s1, &s1len, npp1);
! stripped_name(&s2, &s2len, npp2);
return (strcmp(s1, s2));
}
}
! #define NAME_CHUNK 512
! #define ROUNDLEN(x) (((x) + NAME_CHUNK - 1) / NAME_CHUNK * NAME_CHUNK)
! static void
! adjust_size(char **pp, size_t *lenp, const char *name)
{
! void *newp;
! size_t nlen = strlen(name);
! size_t buflen;
!
! if (*lenp > nlen) {
! (void) memset(*pp, '\0', *lenp);
! return;
! }
!
! buflen = ROUNDLEN(nlen + 1);
! if ((newp = realloc(*pp, buflen)) == NULL) {
! (void) fprintf(stderr,
! "gprof: out of memory comparing names\n");
! exit(EXIT_FAILURE);
! }
! (void) memset(newp, '\0', buflen);
!
! *lenp = buflen;
! *pp = newp;
! }
!
! static void
! stripped_name(char **sp, size_t *slenp, nltype **npp)
! {
! const char *name, *d;
char *c;
! name = d = demangled_name(*npp);
! adjust_size(sp, slenp, name);
! c = *sp;
while ((*d != '(') && (*d != '\0')) {
if (*d != ':')
*c++ = *d++;
else
d++;
}
*c = '\0';
+
+ if ((*npp)->name != name)
+ free((void *)name);
}
/*
* Checks if the current symbol name is the same as its neighbour and
* returns TRUE if it is.
*** 970,984 ****
namesortnlp[nnames++] = &(mi->nl[index]);
}
}
- if (Cflag) {
- s1 = malloc(500 * sizeof (char));
- s2 = malloc(500 * sizeof (char));
- }
-
qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
for (index = 1, todo = nnames; index <= ncycle; index++)
namesortnlp[todo++] = &cyclenl[index];
--- 1001,1010 ----
*** 1036,1052 ****
const char *d = demangled_name(nlp);
if (does_clash(namesortnlp, i, nnames)) {
(void) printf("%6.6s %d:%s\n",
peterbuffer, nlp->module->id, d);
! } else
(void) printf("%6.6s %s\n", peterbuffer,
d);
! if (d != nlp->name)
(void) printf("%6.6s [%s]", "",
nlp->name);
} else {
(void) printf("%6.6s ", peterbuffer);
(void) sprintf(peterbuffer, "<cycle %d>",
nlp->cycleno);
(void) printf("%-33.33s", peterbuffer);
--- 1062,1081 ----
const char *d = demangled_name(nlp);
if (does_clash(namesortnlp, i, nnames)) {
(void) printf("%6.6s %d:%s\n",
peterbuffer, nlp->module->id, d);
! } else {
(void) printf("%6.6s %s\n", peterbuffer,
d);
+ }
! if (d != nlp->name) {
(void) printf("%6.6s [%s]", "",
nlp->name);
+ free((void *)d);
+ }
} else {
(void) printf("%6.6s ", peterbuffer);
(void) sprintf(peterbuffer, "<cycle %d>",
nlp->cycleno);
(void) printf("%-33.33s", peterbuffer);