diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 10cdbad7605..297337649c2 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -22,9 +22,19 @@ int symbol__alloc_hist(struct symbol *sym, int nevents) | |||
22 | notes->sizeof_sym_hist = (sizeof(*notes->histograms) + | 22 | notes->sizeof_sym_hist = (sizeof(*notes->histograms) + |
23 | (sym->end - sym->start) * sizeof(u64)); | 23 | (sym->end - sym->start) * sizeof(u64)); |
24 | notes->histograms = calloc(nevents, notes->sizeof_sym_hist); | 24 | notes->histograms = calloc(nevents, notes->sizeof_sym_hist); |
25 | notes->nr_histograms = nevents; | ||
25 | return notes->histograms == NULL ? -1 : 0; | 26 | return notes->histograms == NULL ? -1 : 0; |
26 | } | 27 | } |
27 | 28 | ||
29 | void symbol__annotate_zero_histograms(struct symbol *sym) | ||
30 | { | ||
31 | struct annotation *notes = symbol__annotation(sym); | ||
32 | |||
33 | if (notes->histograms != NULL) | ||
34 | memset(notes->histograms, 0, | ||
35 | notes->nr_histograms * notes->sizeof_sym_hist); | ||
36 | } | ||
37 | |||
28 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 38 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
29 | int evidx, u64 addr) | 39 | int evidx, u64 addr) |
30 | { | 40 | { |
@@ -85,9 +95,10 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
85 | return NULL; | 95 | return NULL; |
86 | } | 96 | } |
87 | 97 | ||
88 | static void objdump_line__print(struct objdump_line *oline, | 98 | static int objdump_line__print(struct objdump_line *oline, |
89 | struct list_head *head, struct symbol *sym, | 99 | struct list_head *head, struct symbol *sym, |
90 | int evidx, u64 len, int min_pcnt) | 100 | int evidx, u64 len, int min_pcnt, |
101 | int printed, int max_lines) | ||
91 | { | 102 | { |
92 | static const char *prev_line; | 103 | static const char *prev_line; |
93 | static const char *prev_color; | 104 | static const char *prev_color; |
@@ -119,7 +130,10 @@ static void objdump_line__print(struct objdump_line *oline, | |||
119 | percent = 100.0 * hits / h->sum; | 130 | percent = 100.0 * hits / h->sum; |
120 | 131 | ||
121 | if (percent < min_pcnt) | 132 | if (percent < min_pcnt) |
122 | return; | 133 | return -1; |
134 | |||
135 | if (printed >= max_lines) | ||
136 | return 1; | ||
123 | 137 | ||
124 | color = get_percent_color(percent); | 138 | color = get_percent_color(percent); |
125 | 139 | ||
@@ -140,12 +154,16 @@ static void objdump_line__print(struct objdump_line *oline, | |||
140 | color_fprintf(stdout, color, " %7.2f", percent); | 154 | color_fprintf(stdout, color, " %7.2f", percent); |
141 | printf(" : "); | 155 | printf(" : "); |
142 | color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); | 156 | color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line); |
143 | } else { | 157 | } else if (printed >= max_lines) |
158 | return 1; | ||
159 | else { | ||
144 | if (!*oline->line) | 160 | if (!*oline->line) |
145 | printf(" :\n"); | 161 | printf(" :\n"); |
146 | else | 162 | else |
147 | printf(" : %s\n", oline->line); | 163 | printf(" : %s\n", oline->line); |
148 | } | 164 | } |
165 | |||
166 | return 0; | ||
149 | } | 167 | } |
150 | 168 | ||
151 | static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE *file, | 169 | static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE *file, |
@@ -421,14 +439,15 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx) | |||
421 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 439 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); |
422 | } | 440 | } |
423 | 441 | ||
424 | void symbol__annotate_printf(struct symbol *sym, struct map *map, | 442 | int symbol__annotate_printf(struct symbol *sym, struct map *map, |
425 | struct list_head *head, int evidx, bool full_paths, | 443 | struct list_head *head, int evidx, bool full_paths, |
426 | int min_pcnt, int max_lines) | 444 | int min_pcnt, int max_lines) |
427 | { | 445 | { |
428 | struct dso *dso = map->dso; | 446 | struct dso *dso = map->dso; |
429 | const char *filename = dso->long_name, *d_filename; | 447 | const char *filename = dso->long_name, *d_filename; |
430 | struct objdump_line *pos; | 448 | struct objdump_line *pos; |
431 | int printed = 2; | 449 | int printed = 2; |
450 | int more = 0; | ||
432 | u64 len; | 451 | u64 len; |
433 | 452 | ||
434 | if (full_paths) | 453 | if (full_paths) |
@@ -445,10 +464,47 @@ void symbol__annotate_printf(struct symbol *sym, struct map *map, | |||
445 | symbol__annotate_hits(sym, evidx); | 464 | symbol__annotate_hits(sym, evidx); |
446 | 465 | ||
447 | list_for_each_entry(pos, head, node) { | 466 | list_for_each_entry(pos, head, node) { |
448 | objdump_line__print(pos, head, sym, evidx, len, min_pcnt); | 467 | switch (objdump_line__print(pos, head, sym, evidx, len, min_pcnt, |
449 | if (max_lines && ++printed >= max_lines) | 468 | printed, max_lines)) { |
469 | case 0: | ||
470 | ++printed; | ||
471 | break; | ||
472 | case 1: | ||
473 | /* filtered by max_lines */ | ||
474 | ++more; | ||
450 | break; | 475 | break; |
476 | case -1: | ||
477 | default: | ||
478 | /* filtered by min_pcnt */ | ||
479 | break; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | return more; | ||
484 | } | ||
451 | 485 | ||
486 | void symbol__annotate_zero_histogram(struct symbol *sym, int evidx) | ||
487 | { | ||
488 | struct annotation *notes = symbol__annotation(sym); | ||
489 | struct sym_hist *h = annotation__histogram(notes, evidx); | ||
490 | |||
491 | memset(h, 0, notes->sizeof_sym_hist); | ||
492 | } | ||
493 | |||
494 | void symbol__annotate_decay_histogram(struct symbol *sym, | ||
495 | struct list_head *head, int evidx) | ||
496 | { | ||
497 | struct annotation *notes = symbol__annotation(sym); | ||
498 | struct sym_hist *h = annotation__histogram(notes, evidx); | ||
499 | struct objdump_line *pos; | ||
500 | |||
501 | h->sum = 0; | ||
502 | |||
503 | list_for_each_entry(pos, head, node) { | ||
504 | if (pos->offset != -1) { | ||
505 | h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; | ||
506 | h->sum += h->addr[pos->offset]; | ||
507 | } | ||
452 | } | 508 | } |
453 | } | 509 | } |
454 | 510 | ||