diff options
author | Pekka Enberg <penberg@cs.helsinki.fi> | 2009-06-08 18:12:48 (GMT) |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-08 21:10:44 (GMT) |
commit | 80d496be89ed7dede5abee5c057634e80a31c82d (patch) | |
tree | f3a7d3b9f7d08fc300ae0c3ae1554598311fccb1 /tools/perf/util | |
parent | dab5855b12411334355ba21349a06700e4ae7a3b (diff) | |
download | linux-80d496be89ed7dede5abee5c057634e80a31c82d.tar.xz |
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@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: a.p.zijlstra@chello.nl
Cc: acme@redhat.com
LKML-Reference: <Pine.LNX.4.64.0906082111590.12407@melkki.cs.Helsinki.FI>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/symbol.c | 65 |
1 files changed, 65 insertions, 0 deletions
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) { |