aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-13 03:50:21 -0400
committerIngo Molnar <mingo@kernel.org>2012-04-13 03:50:21 -0400
commit659c36fcda403013a01b85da07cf2d9711e6d6c7 (patch)
treeece2e7d0e2c19ea5a3d0ec172ad0b81a8a19021d /tools/perf/util/annotate.c
parent9521d830b6341d1887dcfc2aebde23fbfa5f1473 (diff)
parent5a7ed29c7572d00a75e8c4529e30c5ac2ef82271 (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.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index e5a462f1d07c..1e7fd52bd29d 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)
28int symbol__alloc_hist(struct symbol *sym) 28int symbol__alloc_hist(struct symbol *sym)
29{ 29{
30 struct annotation *notes = symbol__annotation(sym); 30 struct annotation *notes = symbol__annotation(sym);
31 size_t sizeof_sym_hist = (sizeof(struct sym_hist) + 31 const size_t size = sym->end - sym->start + 1;
32 (sym->end - sym->start) * sizeof(u64)); 32 size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));
33 33
34 notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist); 34 notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
35 if (notes->src == NULL) 35 if (notes->src == NULL)
@@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
64 64
65 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 65 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
66 66
67 if (addr >= sym->end) 67 if (addr < sym->start || addr > sym->end)
68 return 0; 68 return -ERANGE;
69 69
70 offset = addr - sym->start; 70 offset = addr - sym->start;
71 h = annotation__histogram(notes, evidx); 71 h = annotation__histogram(notes, evidx);
@@ -84,10 +84,15 @@ static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t pri
84 84
85 if (self != NULL) { 85 if (self != NULL) {
86 self->offset = offset; 86 self->offset = offset;
87 self->line = line; 87 self->line = strdup(line);
88 if (self->line == NULL)
89 goto out_delete;
88 } 90 }
89 91
90 return self; 92 return self;
93out_delete:
94 free(self);
95 return NULL;
91} 96}
92 97
93void objdump_line__free(struct objdump_line *self) 98void objdump_line__free(struct objdump_line *self)
@@ -112,7 +117,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
112} 117}
113 118
114static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, 119static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
115 int evidx, u64 len, int min_pcnt, 120 u64 start, int evidx, u64 len, int min_pcnt,
116 int printed, int max_lines, 121 int printed, int max_lines,
117 struct objdump_line *queue) 122 struct objdump_line *queue)
118{ 123{
@@ -128,6 +133,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
128 struct source_line *src_line = notes->src->lines; 133 struct source_line *src_line = notes->src->lines;
129 struct sym_hist *h = annotation__histogram(notes, evidx); 134 struct sym_hist *h = annotation__histogram(notes, evidx);
130 s64 offset = oline->offset; 135 s64 offset = oline->offset;
136 const u64 addr = start + offset;
131 struct objdump_line *next; 137 struct objdump_line *next;
132 138
133 next = objdump__get_next_ip_line(&notes->src->source, oline); 139 next = objdump__get_next_ip_line(&notes->src->source, oline);
@@ -157,7 +163,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
157 list_for_each_entry_from(queue, &notes->src->source, node) { 163 list_for_each_entry_from(queue, &notes->src->source, node) {
158 if (queue == oline) 164 if (queue == oline)
159 break; 165 break;
160 objdump_line__print(queue, sym, evidx, len, 166 objdump_line__print(queue, sym, start, evidx, len,
161 0, 0, 1, NULL); 167 0, 0, 1, NULL);
162 } 168 }
163 } 169 }
@@ -180,6 +186,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
180 186
181 color_fprintf(stdout, color, " %7.2f", percent); 187 color_fprintf(stdout, color, " %7.2f", percent);
182 printf(" : "); 188 printf(" : ");
189 color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr);
183 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); 190 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line);
184 } else if (max_lines && printed >= max_lines) 191 } else if (max_lines && printed >= max_lines)
185 return 1; 192 return 1;
@@ -201,7 +208,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
201{ 208{
202 struct annotation *notes = symbol__annotation(sym); 209 struct annotation *notes = symbol__annotation(sym);
203 struct objdump_line *objdump_line; 210 struct objdump_line *objdump_line;
204 char *line = NULL, *tmp, *tmp2, *c; 211 char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
205 size_t line_len; 212 size_t line_len;
206 s64 line_ip, offset = -1; 213 s64 line_ip, offset = -1;
207 214
@@ -219,6 +226,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
219 *c = 0; 226 *c = 0;
220 227
221 line_ip = -1; 228 line_ip = -1;
229 parsed_line = line;
222 230
223 /* 231 /*
224 * Strip leading spaces: 232 * Strip leading spaces:
@@ -246,13 +254,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
246 offset = line_ip - start; 254 offset = line_ip - start;
247 if (offset < 0 || (u64)line_ip > end) 255 if (offset < 0 || (u64)line_ip > end)
248 offset = -1; 256 offset = -1;
257 else
258 parsed_line = tmp2 + 1;
249 } 259 }
250 260
251 objdump_line = objdump_line__new(offset, line, privsize); 261 objdump_line = objdump_line__new(offset, parsed_line, privsize);
252 if (objdump_line == NULL) { 262 free(line);
253 free(line); 263
264 if (objdump_line == NULL)
254 return -1; 265 return -1;
255 } 266
256 objdump__add_line(&notes->src->source, objdump_line); 267 objdump__add_line(&notes->src->source, objdump_line);
257 268
258 return 0; 269 return 0;
@@ -408,7 +419,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
408 if (!notes->src->lines) 419 if (!notes->src->lines)
409 return -1; 420 return -1;
410 421
411 start = map->unmap_ip(map, sym->start); 422 start = map__rip_2objdump(map, sym->start);
412 423
413 for (i = 0; i < len; i++) { 424 for (i = 0; i < len; i++) {
414 char *path = NULL; 425 char *path = NULL;
@@ -493,6 +504,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
493 const char *filename = dso->long_name, *d_filename; 504 const char *filename = dso->long_name, *d_filename;
494 struct annotation *notes = symbol__annotation(sym); 505 struct annotation *notes = symbol__annotation(sym);
495 struct objdump_line *pos, *queue = NULL; 506 struct objdump_line *pos, *queue = NULL;
507 u64 start = map__rip_2objdump(map, sym->start);
496 int printed = 2, queue_len = 0; 508 int printed = 2, queue_len = 0;
497 int more = 0; 509 int more = 0;
498 u64 len; 510 u64 len;
@@ -516,8 +528,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
516 queue_len = 0; 528 queue_len = 0;
517 } 529 }
518 530
519 switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, 531 switch (objdump_line__print(pos, sym, start, evidx, len,
520 printed, max_lines, queue)) { 532 min_pcnt, printed, max_lines,
533 queue)) {
521 case 0: 534 case 0:
522 ++printed; 535 ++printed;
523 if (context) { 536 if (context) {
@@ -561,16 +574,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
561{ 574{
562 struct annotation *notes = symbol__annotation(sym); 575 struct annotation *notes = symbol__annotation(sym);
563 struct sym_hist *h = annotation__histogram(notes, evidx); 576 struct sym_hist *h = annotation__histogram(notes, evidx);
564 struct objdump_line *pos; 577 int len = sym->end - sym->start, offset;
565 int len = sym->end - sym->start;
566 578
567 h->sum = 0; 579 h->sum = 0;
568 580 for (offset = 0; offset < len; ++offset) {
569 list_for_each_entry(pos, &notes->src->source, node) { 581 h->addr[offset] = h->addr[offset] * 7 / 8;
570 if (pos->offset != -1 && pos->offset < len) { 582 h->sum += h->addr[offset];
571 h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8;
572 h->sum += h->addr[pos->offset];
573 }
574 } 583 }
575} 584}
576 585