aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 6db435167d7..c777bdaf91d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -14,25 +14,39 @@
14#include "symbol.h" 14#include "symbol.h"
15#include "debug.h" 15#include "debug.h"
16#include "annotate.h" 16#include "annotate.h"
17#include <pthread.h>
17 18
18int symbol__alloc_hist(struct symbol *sym, int nevents) 19int symbol__annotate_init(struct map *map __used, struct symbol *sym)
19{ 20{
20 struct annotation *notes = symbol__annotation(sym); 21 struct annotation *notes = symbol__annotation(sym);
22 pthread_mutex_init(&notes->lock, NULL);
23 return 0;
24}
21 25
22 notes->sizeof_sym_hist = (sizeof(*notes->histograms) + 26int symbol__alloc_hist(struct symbol *sym, int nevents)
27{
28 struct annotation *notes = symbol__annotation(sym);
29 size_t sizeof_sym_hist = (sizeof(struct sym_hist) +
23 (sym->end - sym->start) * sizeof(u64)); 30 (sym->end - sym->start) * sizeof(u64));
24 notes->histograms = calloc(nevents, notes->sizeof_sym_hist); 31
25 notes->nr_histograms = nevents; 32 notes->src = zalloc(sizeof(*notes->src) + nevents * sizeof_sym_hist);
26 return notes->histograms == NULL ? -1 : 0; 33 if (notes->src == NULL)
34 return -1;
35 notes->src->sizeof_sym_hist = sizeof_sym_hist;
36 notes->src->nr_histograms = nevents;
37 INIT_LIST_HEAD(&notes->src->source);
38 return 0;
27} 39}
28 40
29void symbol__annotate_zero_histograms(struct symbol *sym) 41void symbol__annotate_zero_histograms(struct symbol *sym)
30{ 42{
31 struct annotation *notes = symbol__annotation(sym); 43 struct annotation *notes = symbol__annotation(sym);
32 44
33 if (notes->histograms != NULL) 45 pthread_mutex_lock(&notes->lock);
34 memset(notes->histograms, 0, 46 if (notes->src != NULL)
35 notes->nr_histograms * notes->sizeof_sym_hist); 47 memset(notes->src->histograms, 0,
48 notes->src->nr_histograms * notes->src->sizeof_sym_hist);
49 pthread_mutex_unlock(&notes->lock);
36} 50}
37 51
38int symbol__inc_addr_samples(struct symbol *sym, struct map *map, 52int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
@@ -43,7 +57,7 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
43 struct sym_hist *h; 57 struct sym_hist *h;
44 58
45 notes = symbol__annotation(sym); 59 notes = symbol__annotation(sym);
46 if (notes->histograms == NULL) 60 if (notes->src == NULL)
47 return -ENOMEM; 61 return -ENOMEM;
48 62
49 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 63 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
@@ -95,8 +109,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
95 return NULL; 109 return NULL;
96} 110}
97 111
98static int objdump_line__print(struct objdump_line *oline, 112static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
99 struct list_head *head, struct symbol *sym,
100 int evidx, u64 len, int min_pcnt, 113 int evidx, u64 len, int min_pcnt,
101 int printed, int max_lines) 114 int printed, int max_lines)
102{ 115{
@@ -109,10 +122,12 @@ static int objdump_line__print(struct objdump_line *oline,
109 double percent = 0.0; 122 double percent = 0.0;
110 const char *color; 123 const char *color;
111 struct annotation *notes = symbol__annotation(sym); 124 struct annotation *notes = symbol__annotation(sym);
112 struct source_line *src_line = notes->src_line; 125 struct source_line *src_line = notes->src->lines;
113 struct sym_hist *h = annotation__histogram(notes, evidx); 126 struct sym_hist *h = annotation__histogram(notes, evidx);
114 s64 offset = oline->offset; 127 s64 offset = oline->offset;
115 struct objdump_line *next = objdump__get_next_ip_line(head, oline); 128 struct objdump_line *next;
129
130 next = objdump__get_next_ip_line(&notes->src->source, oline);
116 131
117 while (offset < (s64)len && 132 while (offset < (s64)len &&
118 (next == NULL || offset < next->offset)) { 133 (next == NULL || offset < next->offset)) {
@@ -166,9 +181,10 @@ static int objdump_line__print(struct objdump_line *oline,
166 return 0; 181 return 0;
167} 182}
168 183
169static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE *file, 184static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
170 struct list_head *head, size_t privsize) 185 FILE *file, size_t privsize)
171{ 186{
187 struct annotation *notes = symbol__annotation(sym);
172 struct objdump_line *objdump_line; 188 struct objdump_line *objdump_line;
173 char *line = NULL, *tmp, *tmp2, *c; 189 char *line = NULL, *tmp, *tmp2, *c;
174 size_t line_len; 190 size_t line_len;
@@ -222,13 +238,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE
222 free(line); 238 free(line);
223 return -1; 239 return -1;
224 } 240 }
225 objdump__add_line(head, objdump_line); 241 objdump__add_line(&notes->src->source, objdump_line);
226 242
227 return 0; 243 return 0;
228} 244}
229 245
230int symbol__annotate(struct symbol *sym, struct map *map, 246int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
231 struct list_head *head, size_t privsize)
232{ 247{
233 struct dso *dso = map->dso; 248 struct dso *dso = map->dso;
234 char *filename = dso__build_id_filename(dso, NULL, 0); 249 char *filename = dso__build_id_filename(dso, NULL, 0);
@@ -297,7 +312,7 @@ fallback:
297 goto out_free_filename; 312 goto out_free_filename;
298 313
299 while (!feof(file)) 314 while (!feof(file))
300 if (symbol__parse_objdump_line(sym, map, file, head, privsize) < 0) 315 if (symbol__parse_objdump_line(sym, map, file, privsize) < 0)
301 break; 316 break;
302 317
303 pclose(file); 318 pclose(file);
@@ -330,14 +345,14 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
330static void symbol__free_source_line(struct symbol *sym, int len) 345static void symbol__free_source_line(struct symbol *sym, int len)
331{ 346{
332 struct annotation *notes = symbol__annotation(sym); 347 struct annotation *notes = symbol__annotation(sym);
333 struct source_line *src_line = notes->src_line; 348 struct source_line *src_line = notes->src->lines;
334 int i; 349 int i;
335 350
336 for (i = 0; i < len; i++) 351 for (i = 0; i < len; i++)
337 free(src_line[i].path); 352 free(src_line[i].path);
338 353
339 free(src_line); 354 free(src_line);
340 notes->src_line = NULL; 355 notes->src->lines = NULL;
341} 356}
342 357
343/* Get the filename:line for the colored entries */ 358/* Get the filename:line for the colored entries */
@@ -355,8 +370,8 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
355 if (!h->sum) 370 if (!h->sum)
356 return 0; 371 return 0;
357 372
358 src_line = notes->src_line = calloc(len, sizeof(struct source_line)); 373 src_line = notes->src->lines = calloc(len, sizeof(struct source_line));
359 if (!notes->src_line) 374 if (!notes->src->lines)
360 return -1; 375 return -1;
361 376
362 start = map->unmap_ip(map, sym->start); 377 start = map->unmap_ip(map, sym->start);
@@ -436,12 +451,12 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx)
436 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); 451 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
437} 452}
438 453
439int symbol__annotate_printf(struct symbol *sym, struct map *map, 454int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
440 struct list_head *head, int evidx, bool full_paths, 455 bool full_paths, int min_pcnt, int max_lines)
441 int min_pcnt, int max_lines)
442{ 456{
443 struct dso *dso = map->dso; 457 struct dso *dso = map->dso;
444 const char *filename = dso->long_name, *d_filename; 458 const char *filename = dso->long_name, *d_filename;
459 struct annotation *notes = symbol__annotation(sym);
445 struct objdump_line *pos; 460 struct objdump_line *pos;
446 int printed = 2; 461 int printed = 2;
447 int more = 0; 462 int more = 0;
@@ -460,8 +475,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
460 if (verbose) 475 if (verbose)
461 symbol__annotate_hits(sym, evidx); 476 symbol__annotate_hits(sym, evidx);
462 477
463 list_for_each_entry(pos, head, node) { 478 list_for_each_entry(pos, &notes->src->source, node) {
464 switch (objdump_line__print(pos, head, sym, evidx, len, min_pcnt, 479 switch (objdump_line__print(pos, sym, evidx, len, min_pcnt,
465 printed, max_lines)) { 480 printed, max_lines)) {
466 case 0: 481 case 0:
467 ++printed; 482 ++printed;
@@ -485,11 +500,10 @@ void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
485 struct annotation *notes = symbol__annotation(sym); 500 struct annotation *notes = symbol__annotation(sym);
486 struct sym_hist *h = annotation__histogram(notes, evidx); 501 struct sym_hist *h = annotation__histogram(notes, evidx);
487 502
488 memset(h, 0, notes->sizeof_sym_hist); 503 memset(h, 0, notes->src->sizeof_sym_hist);
489} 504}
490 505
491void symbol__annotate_decay_histogram(struct symbol *sym, 506void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
492 struct list_head *head, int evidx)
493{ 507{
494 struct annotation *notes = symbol__annotation(sym); 508 struct annotation *notes = symbol__annotation(sym);
495 struct sym_hist *h = annotation__histogram(notes, evidx); 509 struct sym_hist *h = annotation__histogram(notes, evidx);
@@ -497,7 +511,7 @@ void symbol__annotate_decay_histogram(struct symbol *sym,
497 511
498 h->sum = 0; 512 h->sum = 0;
499 513
500 list_for_each_entry(pos, head, node) { 514 list_for_each_entry(pos, &notes->src->source, node) {
501 if (pos->offset != -1) { 515 if (pos->offset != -1) {
502 h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; 516 h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8;
503 h->sum += h->addr[pos->offset]; 517 h->sum += h->addr[pos->offset];
@@ -522,10 +536,9 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
522 struct dso *dso = map->dso; 536 struct dso *dso = map->dso;
523 const char *filename = dso->long_name; 537 const char *filename = dso->long_name;
524 struct rb_root source_line = RB_ROOT; 538 struct rb_root source_line = RB_ROOT;
525 LIST_HEAD(head);
526 u64 len; 539 u64 len;
527 540
528 if (symbol__annotate(sym, map, &head, 0) < 0) 541 if (symbol__annotate(sym, map, 0) < 0)
529 return -1; 542 return -1;
530 543
531 len = sym->end - sym->start; 544 len = sym->end - sym->start;
@@ -536,12 +549,12 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
536 print_summary(&source_line, filename); 549 print_summary(&source_line, filename);
537 } 550 }
538 551
539 symbol__annotate_printf(sym, map, &head, evidx, full_paths, 552 symbol__annotate_printf(sym, map, evidx, full_paths,
540 min_pcnt, max_lines); 553 min_pcnt, max_lines);
541 if (print_lines) 554 if (print_lines)
542 symbol__free_source_line(sym, len); 555 symbol__free_source_line(sym, len);
543 556
544 objdump_line_list__purge(&head); 557 objdump_line_list__purge(&symbol__annotation(sym)->src->source);
545 558
546 return 0; 559 return 0;
547} 560}