aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-02-08 12:29:25 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-02-08 12:29:25 -0500
commitd5e3d747007fdb541e57ed72e020ff0b94db3470 (patch)
tree96dc1bf70895e24f3b85f44ee03cd0896105762a /tools/perf/util/annotate.c
parentce6f4fab4059cd72638a0cfa596a8ee2c79c1c8e (diff)
perf annotate: Fix annotate context lines regression
The live annotation done in 'perf top' needs to limit the context before lines that aren't filtered out by the min percent filter, if we don't do that, the screen in a tty often is not enough for showing what is interesting: lines with hits and a few source code lines before it. Reported-by: Mike Galbraith <efault@gmx.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c47
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
112static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, 112static 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, &notes->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
454int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, 467int 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, &notes->src->source, node) { 492 list_for_each_entry(pos, &notes->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