diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 9b25575b980c..7488fe99502c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -15,44 +15,40 @@ | |||
15 | #include "debug.h" | 15 | #include "debug.h" |
16 | #include "annotate.h" | 16 | #include "annotate.h" |
17 | 17 | ||
18 | static int symbol__alloc_hist(struct symbol *sym) | 18 | int symbol__alloc_hist(struct symbol *sym, int nevents) |
19 | { | 19 | { |
20 | struct annotation *notes = symbol__annotation(sym); | 20 | struct annotation *notes = symbol__annotation(sym); |
21 | const int size = (sizeof(*notes->histogram) + | ||
22 | (sym->end - sym->start) * sizeof(u64)); | ||
23 | 21 | ||
24 | notes->histogram = zalloc(size); | 22 | notes->sizeof_sym_hist = (sizeof(*notes->histograms) + |
25 | return notes->histogram == NULL ? -1 : 0; | 23 | (sym->end - sym->start) * sizeof(u64)); |
24 | notes->histograms = calloc(nevents, notes->sizeof_sym_hist); | ||
25 | return notes->histograms == NULL ? -1 : 0; | ||
26 | } | 26 | } |
27 | 27 | ||
28 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, u64 addr) | 28 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
29 | int evidx, u64 addr) | ||
29 | { | 30 | { |
30 | unsigned int sym_size, offset; | 31 | unsigned offset; |
31 | struct annotation *notes; | 32 | struct annotation *notes; |
32 | struct sym_hist *h; | 33 | struct sym_hist *h; |
33 | 34 | ||
34 | if (!sym || !map) | ||
35 | return 0; | ||
36 | |||
37 | notes = symbol__annotation(sym); | 35 | notes = symbol__annotation(sym); |
38 | if (notes->histogram == NULL && symbol__alloc_hist(sym) < 0) | 36 | if (notes->histograms == NULL) |
39 | return -ENOMEM; | 37 | return -ENOMEM; |
40 | 38 | ||
41 | sym_size = sym->end - sym->start; | ||
42 | offset = addr - sym->start; | ||
43 | |||
44 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 39 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
45 | 40 | ||
46 | if (offset >= sym_size) | 41 | if (addr >= sym->end) |
47 | return 0; | 42 | return 0; |
48 | 43 | ||
49 | h = notes->histogram; | 44 | offset = addr - sym->start; |
45 | h = annotation__histogram(notes, evidx); | ||
50 | h->sum++; | 46 | h->sum++; |
51 | h->addr[offset]++; | 47 | h->addr[offset]++; |
52 | 48 | ||
53 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 | 49 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 |
54 | "] => %" PRIu64 "\n", sym->start, sym->name, | 50 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, |
55 | addr, addr - sym->start, h->addr[offset]); | 51 | addr, addr - sym->start, evidx, h->addr[offset]); |
56 | return 0; | 52 | return 0; |
57 | } | 53 | } |
58 | 54 | ||
@@ -90,8 +86,8 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
90 | } | 86 | } |
91 | 87 | ||
92 | static void objdump_line__print(struct objdump_line *oline, | 88 | static void objdump_line__print(struct objdump_line *oline, |
93 | struct list_head *head, | 89 | struct list_head *head, struct symbol *sym, |
94 | struct symbol *sym, u64 len) | 90 | int evidx, u64 len) |
95 | { | 91 | { |
96 | static const char *prev_line; | 92 | static const char *prev_line; |
97 | static const char *prev_color; | 93 | static const char *prev_color; |
@@ -103,7 +99,7 @@ static void objdump_line__print(struct objdump_line *oline, | |||
103 | const char *color; | 99 | const char *color; |
104 | struct annotation *notes = symbol__annotation(sym); | 100 | struct annotation *notes = symbol__annotation(sym); |
105 | struct source_line *src_line = notes->src_line; | 101 | struct source_line *src_line = notes->src_line; |
106 | struct sym_hist *h = notes->histogram; | 102 | struct sym_hist *h = annotation__histogram(notes, evidx); |
107 | s64 offset = oline->offset; | 103 | s64 offset = oline->offset; |
108 | struct objdump_line *next = objdump__get_next_ip_line(head, oline); | 104 | struct objdump_line *next = objdump__get_next_ip_line(head, oline); |
109 | 105 | ||
@@ -328,7 +324,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
328 | 324 | ||
329 | /* Get the filename:line for the colored entries */ | 325 | /* Get the filename:line for the colored entries */ |
330 | static int symbol__get_source_line(struct symbol *sym, struct map *map, | 326 | static int symbol__get_source_line(struct symbol *sym, struct map *map, |
331 | struct rb_root *root, int len, | 327 | int evidx, struct rb_root *root, int len, |
332 | const char *filename) | 328 | const char *filename) |
333 | { | 329 | { |
334 | u64 start; | 330 | u64 start; |
@@ -336,7 +332,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
336 | char cmd[PATH_MAX * 2]; | 332 | char cmd[PATH_MAX * 2]; |
337 | struct source_line *src_line; | 333 | struct source_line *src_line; |
338 | struct annotation *notes = symbol__annotation(sym); | 334 | struct annotation *notes = symbol__annotation(sym); |
339 | struct sym_hist *h = notes->histogram; | 335 | struct sym_hist *h = annotation__histogram(notes, evidx); |
340 | 336 | ||
341 | if (!h->sum) | 337 | if (!h->sum) |
342 | return 0; | 338 | return 0; |
@@ -409,10 +405,10 @@ static void print_summary(struct rb_root *root, const char *filename) | |||
409 | } | 405 | } |
410 | } | 406 | } |
411 | 407 | ||
412 | static void symbol__annotate_hits(struct symbol *sym) | 408 | static void symbol__annotate_hits(struct symbol *sym, int evidx) |
413 | { | 409 | { |
414 | struct annotation *notes = symbol__annotation(sym); | 410 | struct annotation *notes = symbol__annotation(sym); |
415 | struct sym_hist *h = notes->histogram; | 411 | struct sym_hist *h = annotation__histogram(notes, evidx); |
416 | u64 len = sym->end - sym->start, offset; | 412 | u64 len = sym->end - sym->start, offset; |
417 | 413 | ||
418 | for (offset = 0; offset < len; ++offset) | 414 | for (offset = 0; offset < len; ++offset) |
@@ -422,8 +418,8 @@ static void symbol__annotate_hits(struct symbol *sym) | |||
422 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 418 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); |
423 | } | 419 | } |
424 | 420 | ||
425 | int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | 421 | int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, |
426 | bool full_paths) | 422 | bool print_lines, bool full_paths) |
427 | { | 423 | { |
428 | struct dso *dso = map->dso; | 424 | struct dso *dso = map->dso; |
429 | const char *filename = dso->long_name, *d_filename; | 425 | const char *filename = dso->long_name, *d_filename; |
@@ -443,7 +439,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | |||
443 | len = sym->end - sym->start; | 439 | len = sym->end - sym->start; |
444 | 440 | ||
445 | if (print_lines) { | 441 | if (print_lines) { |
446 | symbol__get_source_line(sym, map, &source_line, len, filename); | 442 | symbol__get_source_line(sym, map, evidx, &source_line, |
443 | len, filename); | ||
447 | print_summary(&source_line, filename); | 444 | print_summary(&source_line, filename); |
448 | } | 445 | } |
449 | 446 | ||
@@ -452,10 +449,10 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | |||
452 | printf("------------------------------------------------\n"); | 449 | printf("------------------------------------------------\n"); |
453 | 450 | ||
454 | if (verbose) | 451 | if (verbose) |
455 | symbol__annotate_hits(sym); | 452 | symbol__annotate_hits(sym, evidx); |
456 | 453 | ||
457 | list_for_each_entry_safe(pos, n, &head, node) { | 454 | list_for_each_entry_safe(pos, n, &head, node) { |
458 | objdump_line__print(pos, &head, sym, len); | 455 | objdump_line__print(pos, &head, sym, evidx, len); |
459 | list_del(&pos->node); | 456 | list_del(&pos->node); |
460 | objdump_line__free(pos); | 457 | objdump_line__free(pos); |
461 | } | 458 | } |