aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers/annotate.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-04-24 14:24:28 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-04-24 14:24:28 -0300
commita3f895be1f1ed17f66e6e71adeef0cc7f937512c (patch)
tree167a39caa601782726a483d977e9e4150d5fb3a7 /tools/perf/ui/browsers/annotate.c
parentui browser: Add method to write graphical characters (diff)
downloadlinux-dev-a3f895be1f1ed17f66e6e71adeef0cc7f937512c.tar.xz
linux-dev-a3f895be1f1ed17f66e6e71adeef0cc7f937512c.zip
perf annotate browser: Initial loop detection
Simple algorithm, just look for the next backward jump that points to before the cursor. Then draw an arrow connecting the jump to its target. Do this as you move the cursor, entering/exiting possible loops. Ex (graph chars replaced to avoid mail encoding woes): avc_has_perm_flags 0.00 | nopl 0x0(%rax) 5.36 |+-> 68: mov (%rax),%rax 5.15 || test %rax,%rax 0.00 || v je 130 2.96 || 74: cmp -0x20(%rax),%ebx 47.38 || lea -0x20(%rax),%rcx 0.28 || ^ jne 68 3.16 || cmp -0x18(%rax),%dx 0.00 |+------^ jne 68 4.92 | cmp 0x4(%rcx),%r13d 0.00 | v jne 68 1.15 | test %rcx,%rcx 0.00 | v je 130 Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-5gairf6or7dazlx3ocxwvftm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r--tools/perf/ui/browsers/annotate.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index c3fc6f39f901..9e3310cd02cd 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -94,13 +94,13 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
addr += ab->start;
if (!ab->use_offset) {
- printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ":", addr);
+ printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr);
} else {
if (bdl->jump_target) {
- printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ":",
+ printed = scnprintf(bf, sizeof(bf), " %*" PRIx64 ":",
ab->offset_width, addr);
} else {
- printed = scnprintf(bf, sizeof(bf), "%*s ",
+ printed = scnprintf(bf, sizeof(bf), " %*s ",
ab->offset_width, " ");
}
}
@@ -141,6 +141,59 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
ab->selection = dl;
}
+static void annotate_browser__draw_current_loop(struct ui_browser *browser)
+{
+ struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
+ struct map_symbol *ms = browser->priv;
+ struct symbol *sym = ms->sym;
+ struct annotation *notes = symbol__annotation(sym);
+ struct disasm_line *cursor = ab->selection, *pos = cursor, *target;
+ struct browser_disasm_line *bcursor = disasm_line__browser(cursor),
+ *btarget, *bpos;
+ unsigned int from, to, start_width = 2;
+
+ list_for_each_entry_from(pos, &notes->src->source, node) {
+ if (!pos->ins || !ins__is_jump(pos->ins))
+ continue;
+
+ target = ab->offsets[pos->ops.target];
+ if (!target)
+ continue;
+
+ btarget = disasm_line__browser(target);
+ if (btarget->idx <= bcursor->idx)
+ goto found;
+ }
+
+ return;
+
+found:
+ bpos = disasm_line__browser(pos);
+ if (ab->hide_src_code) {
+ from = bpos->idx_asm;
+ to = btarget->idx_asm;
+ } else {
+ from = (u64)bpos->idx;
+ to = (u64)btarget->idx;
+ }
+
+ ui_browser__set_color(browser, HE_COLORSET_CODE);
+
+ if (!bpos->jump_target)
+ start_width += ab->offset_width + 1;
+
+ __ui_browser__line_arrow_up(browser, 10, from, to, start_width);
+}
+
+static unsigned int annotate_browser__refresh(struct ui_browser *browser)
+{
+ int ret = ui_browser__list_head_refresh(browser);
+
+ annotate_browser__draw_current_loop(browser);
+
+ return ret;
+}
+
static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *sym, int evidx)
{
double percent = 0.0;
@@ -666,7 +719,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
};
struct annotate_browser browser = {
.b = {
- .refresh = ui_browser__list_head_refresh,
+ .refresh = annotate_browser__refresh,
.seek = ui_browser__list_head_seek,
.write = annotate_browser__write,
.filter = disasm_line__filter,