diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c777bdaf91da..02976b895f27 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -111,7 +111,8 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
111 | 111 | ||
112 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | 112 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, |
113 | int evidx, u64 len, int min_pcnt, | 113 | int evidx, u64 len, int min_pcnt, |
114 | int printed, int max_lines) | 114 | int printed, int max_lines, |
115 | struct objdump_line *queue) | ||
115 | { | 116 | { |
116 | static const char *prev_line; | 117 | static const char *prev_line; |
117 | static const char *prev_color; | 118 | static const char *prev_color; |
@@ -150,6 +151,15 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
150 | if (max_lines && printed >= max_lines) | 151 | if (max_lines && printed >= max_lines) |
151 | return 1; | 152 | return 1; |
152 | 153 | ||
154 | if (queue != NULL) { | ||
155 | list_for_each_entry_from(queue, ¬es->src->source, node) { | ||
156 | if (queue == oline) | ||
157 | break; | ||
158 | objdump_line__print(queue, sym, evidx, len, | ||
159 | 0, 0, 1, NULL); | ||
160 | } | ||
161 | } | ||
162 | |||
153 | color = get_percent_color(percent); | 163 | color = get_percent_color(percent); |
154 | 164 | ||
155 | /* | 165 | /* |
@@ -172,6 +182,9 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
172 | } else if (max_lines && printed >= max_lines) | 182 | } else if (max_lines && printed >= max_lines) |
173 | return 1; | 183 | return 1; |
174 | else { | 184 | else { |
185 | if (queue) | ||
186 | return -1; | ||
187 | |||
175 | if (!*oline->line) | 188 | if (!*oline->line) |
176 | printf(" :\n"); | 189 | printf(" :\n"); |
177 | else | 190 | else |
@@ -452,13 +465,14 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx) | |||
452 | } | 465 | } |
453 | 466 | ||
454 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | 467 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, |
455 | bool full_paths, int min_pcnt, int max_lines) | 468 | bool full_paths, int min_pcnt, int max_lines, |
469 | int context) | ||
456 | { | 470 | { |
457 | struct dso *dso = map->dso; | 471 | struct dso *dso = map->dso; |
458 | const char *filename = dso->long_name, *d_filename; | 472 | const char *filename = dso->long_name, *d_filename; |
459 | struct annotation *notes = symbol__annotation(sym); | 473 | struct annotation *notes = symbol__annotation(sym); |
460 | struct objdump_line *pos; | 474 | struct objdump_line *pos, *queue = NULL; |
461 | int printed = 2; | 475 | int printed = 2, queue_len = 0; |
462 | int more = 0; | 476 | int more = 0; |
463 | u64 len; | 477 | u64 len; |
464 | 478 | ||
@@ -476,10 +490,20 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
476 | symbol__annotate_hits(sym, evidx); | 490 | symbol__annotate_hits(sym, evidx); |
477 | 491 | ||
478 | list_for_each_entry(pos, ¬es->src->source, node) { | 492 | list_for_each_entry(pos, ¬es->src->source, node) { |
493 | if (context && queue == NULL) { | ||
494 | queue = pos; | ||
495 | queue_len = 0; | ||
496 | } | ||
497 | |||
479 | switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, | 498 | switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, |
480 | printed, max_lines)) { | 499 | printed, max_lines, queue)) { |
481 | case 0: | 500 | case 0: |
482 | ++printed; | 501 | ++printed; |
502 | if (context) { | ||
503 | printed += queue_len; | ||
504 | queue = NULL; | ||
505 | queue_len = 0; | ||
506 | } | ||
483 | break; | 507 | break; |
484 | case 1: | 508 | case 1: |
485 | /* filtered by max_lines */ | 509 | /* filtered by max_lines */ |
@@ -487,7 +511,16 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
487 | break; | 511 | break; |
488 | case -1: | 512 | case -1: |
489 | default: | 513 | default: |
490 | /* filtered by min_pcnt */ | 514 | /* |
515 | * Filtered by min_pcnt or non IP lines when | ||
516 | * context != 0 | ||
517 | */ | ||
518 | if (!context) | ||
519 | break; | ||
520 | if (queue_len == context) | ||
521 | queue = list_entry(queue->node.next, typeof(*queue), node); | ||
522 | else | ||
523 | ++queue_len; | ||
491 | break; | 524 | break; |
492 | } | 525 | } |
493 | } | 526 | } |
@@ -550,7 +583,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, | |||
550 | } | 583 | } |
551 | 584 | ||
552 | symbol__annotate_printf(sym, map, evidx, full_paths, | 585 | symbol__annotate_printf(sym, map, evidx, full_paths, |
553 | min_pcnt, max_lines); | 586 | min_pcnt, max_lines, 0); |
554 | if (print_lines) | 587 | if (print_lines) |
555 | symbol__free_source_line(sym, len); | 588 | symbol__free_source_line(sym, len); |
556 | 589 | ||