[tip:perfcounters/core] perf report: Add support for profiling JIT generated code
From: tip-bot for Pekka Enberg
Date: Mon Jun 08 2009 - 17:34:35 EST
Commit-ID: 80d496be89ed7dede5abee5c057634e80a31c82d
Gitweb: http://git.kernel.org/tip/80d496be89ed7dede5abee5c057634e80a31c82d
Author: Pekka Enberg <penberg@xxxxxxxxxxxxxx>
AuthorDate: Mon, 8 Jun 2009 21:12:48 +0300
Committer: Ingo Molnar <mingo@xxxxxxx>
CommitDate: Mon, 8 Jun 2009 23:10:44 +0200
perf report: Add support for profiling JIT generated code
This patch adds support for profiling JIT generated code to 'perf
report'. A JIT compiler is required to generate a "/tmp/perf-$PID.map"
symbols map that is parsed when looking and displaying symbols.
Thanks to Peter Zijlstra for his help with this patch!
Example "perf report" output with the Jato JIT:
#
# (40311 samples)
#
# Overhead Command Shared Object Symbol
# ........ ................ ......................... ......
#
97.80% jato /tmp/perf-11915.map [.] Fibonacci.fib(I)I
0.56% jato 00000000b7fa023b 0x000000b7fa023b
0.45% jato /tmp/perf-11915.map [.] Fibonacci.main([Ljava/lang/String;)V
0.38% jato [kernel] [k] get_page_from_freelist
0.06% jato [kernel] [k] kunmap_atomic
0.05% jato ./jato [.] utf8Hash
0.04% jato ./jato [.] executeJava
0.04% jato ./jato [.] defineClass
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxxxxxx>
Cc: a.p.zijlstra@xxxxxxxxx
Cc: acme@xxxxxxxxxx
LKML-Reference: <Pine.LNX.4.64.0906082111590.12407@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
---
tools/perf/builtin-report.c | 15 +++++++++-
tools/perf/util/symbol.c | 65 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index f053a74..61d8718 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -209,6 +209,11 @@ static uint64_t vdso__map_ip(struct map *map, uint64_t ip)
return ip;
}
+static inline int is_anon_memory(const char *filename)
+{
+ return strcmp(filename, "//anon") == 0;
+}
+
static struct map *map__new(struct mmap_event *event)
{
struct map *self = malloc(sizeof(*self));
@@ -216,6 +221,7 @@ static struct map *map__new(struct mmap_event *event)
if (self != NULL) {
const char *filename = event->filename;
char newfilename[PATH_MAX];
+ int anon;
if (cwd) {
int n = strcommon(filename);
@@ -227,6 +233,13 @@ static struct map *map__new(struct mmap_event *event)
}
}
+ anon = is_anon_memory(filename);
+
+ if (anon) {
+ snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
+ filename = newfilename;
+ }
+
self->start = event->start;
self->end = event->start + event->len;
self->pgoff = event->pgoff;
@@ -235,7 +248,7 @@ static struct map *map__new(struct mmap_event *event)
if (self->dso == NULL)
goto out_delete;
- if (self->dso == vdso)
+ if (self->dso == vdso || anon)
self->map_ip = vdso__map_ip;
else
self->map_ip = map__map_ip;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 158588c..32dd47d 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -220,6 +220,68 @@ out_failure:
return -1;
}
+static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int verbose)
+{
+ char *line = NULL;
+ size_t n;
+ FILE *file;
+ int nr_syms = 0;
+
+ file = fopen(self->name, "r");
+ if (file == NULL)
+ goto out_failure;
+
+ while (!feof(file)) {
+ __u64 start, size;
+ struct symbol *sym;
+ int line_len, len;
+
+ line_len = getline(&line, &n, file);
+ if (line_len < 0)
+ break;
+
+ if (!line)
+ goto out_failure;
+
+ line[--line_len] = '\0'; /* \n */
+
+ len = hex2u64(line, &start);
+
+ len++;
+ if (len + 2 >= line_len)
+ continue;
+
+ len += hex2u64(line + len, &size);
+
+ len++;
+ if (len + 2 >= line_len)
+ continue;
+
+ sym = symbol__new(start, size, line + len,
+ self->sym_priv_size, start, verbose);
+
+ if (sym == NULL)
+ goto out_delete_line;
+
+ if (filter && filter(self, sym))
+ symbol__delete(sym, self->sym_priv_size);
+ else {
+ dso__insert_symbol(self, sym);
+ nr_syms++;
+ }
+ }
+
+ free(line);
+ fclose(file);
+
+ return nr_syms;
+
+out_delete_line:
+ free(line);
+out_failure:
+ return -1;
+}
+
/**
* elf_symtab__for_each_symbol - iterate thru all the symbols
*
@@ -507,6 +569,9 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
if (!name)
return -1;
+ if (strncmp(self->name, "/tmp/perf-", 10) == 0)
+ return dso__load_perf_map(self, filter, verbose);
+
more:
do {
switch (variant) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/