diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-04-13 09:50:21 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-04-13 09:50:21 +0200 |
commit | 659c36fcda403013a01b85da07cf2d9711e6d6c7 (patch) | |
tree | ece2e7d0e2c19ea5a3d0ec172ad0b81a8a19021d /tools/perf/util/annotate.c | |
parent | 9521d830b6341d1887dcfc2aebde23fbfa5f1473 (diff) | |
parent | 5a7ed29c7572d00a75e8c4529e30c5ac2ef82271 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Fixes and improvements for perf/core:
. Overhaul the tools/ makefiles, gluing them to the top level Makefile, from
Borislav Petkov.
. Move the UI files from tools/perf/util/ui/ to tools/perf/ui/. Also move
the GTK+ browser to tools/perf/ui/gtk/, from Namhyung Kim.
. Only fallback to sw cycles counter on ENOENT for the hw cycles, from
Robert Richter
. Trivial fixes from Robert Richter
. Handle the autogenerated bison/flex files better, from Namhyung and Jiri Olsa.
. Navigate jump instructions in the annotate browser, just press enter or ->,
still needs support for a jump navigation history, i.e. to go back.
. Search string in the annotate browser: same keys as vim:
/ forward
n next backward/forward
? backward
. Clarify number of events/samples in the report header, from Ashay Rane
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e5a462f1d07..1e7fd52bd29 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -28,8 +28,8 @@ int symbol__annotate_init(struct map *map __used, struct symbol *sym) int symbol__alloc_hist(struct symbol *sym) { struct annotation *notes = symbol__annotation(sym); - size_t sizeof_sym_hist = (sizeof(struct sym_hist) + - (sym->end - sym->start) * sizeof(u64)); + const size_t size = sym->end - sym->start + 1; + size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist); if (notes->src == NULL) @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); - if (addr >= sym->end) - return 0; + if (addr < sym->start || addr > sym->end) + return -ERANGE; offset = addr - sym->start; h = annotation__histogram(notes, evidx); @@ -84,10 +84,15 @@ static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t pri if (self != NULL) { self->offset = offset; - self->line = line; + self->line = strdup(line); + if (self->line == NULL) + goto out_delete; } return self; +out_delete: + free(self); + return NULL; } void objdump_line__free(struct objdump_line *self) @@ -112,7 +117,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, } static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, - int evidx, u64 len, int min_pcnt, + u64 start, int evidx, u64 len, int min_pcnt, int printed, int max_lines, struct objdump_line *queue) { @@ -128,6 +133,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, struct source_line *src_line = notes->src->lines; struct sym_hist *h = annotation__histogram(notes, evidx); s64 offset = oline->offset; + const u64 addr = start + offset; struct objdump_line *next; next = objdump__get_next_ip_line(¬es->src->source, oline); @@ -157,7 +163,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, list_for_each_entry_from(queue, ¬es->src->source, node) { if (queue == oline) break; - objdump_line__print(queue, sym, evidx, len, + objdump_line__print(queue, sym, start, evidx, len, 0, 0, 1, NULL); } } @@ -180,6 +186,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, color_fprintf(stdout, color, " %7.2f", percent); printf(" : "); + color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr); color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); } else if (max_lines && printed >= max_lines) return 1; @@ -201,7 +208,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, { struct annotation *notes = symbol__annotation(sym); struct objdump_line *objdump_line; - char *line = NULL, *tmp, *tmp2, *c; + char *line = NULL, *parsed_line, *tmp, *tmp2, *c; size_t line_len; s64 line_ip, offset = -1; @@ -219,6 +226,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, *c = 0; line_ip = -1; + parsed_line = line; /* * Strip leading spaces: @@ -246,13 +254,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, offset = line_ip - start; if (offset < 0 || (u64)line_ip > end) offset = -1; + else + parsed_line = tmp2 + 1; } - objdump_line = objdump_line__new(offset, line, privsize); - if (objdump_line == NULL) { - free(line); + objdump_line = objdump_line__new(offset, parsed_line, privsize); + free(line); + + if (objdump_line == NULL) return -1; - } + objdump__add_line(¬es->src->source, objdump_line); return 0; @@ -408,7 +419,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, if (!notes->src->lines) return -1; - start = map->unmap_ip(map, sym->start); + start = map__rip_2objdump(map, sym->start); for (i = 0; i < len; i++) { char *path = NULL; @@ -493,6 +504,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, const char *filename = dso->long_name, *d_filename; struct annotation *notes = symbol__annotation(sym); struct objdump_line *pos, *queue = NULL; + u64 start = map__rip_2objdump(map, sym->start); int printed = 2, queue_len = 0; int more = 0; u64 len; @@ -516,8 +528,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, queue_len = 0; } - switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, - printed, max_lines, queue)) { + switch (objdump_line__print(pos, sym, start, evidx, len, + min_pcnt, printed, max_lines, + queue)) { case 0: ++printed; if (context) { @@ -561,16 +574,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); - struct objdump_line *pos; - int len = sym->end - sym->start; + int len = sym->end - sym->start, offset; h->sum = 0; - - list_for_each_entry(pos, ¬es->src->source, node) { - if (pos->offset != -1 && pos->offset < len) { - h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; - h->sum += h->addr[pos->offset]; - } + for (offset = 0; offset < len; ++offset) { + h->addr[offset] = h->addr[offset] * 7 / 8; + h->sum += h->addr[offset]; } } |