diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-18 15:07:38 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-18 15:07:38 -0400 |
commit | d86b0597c4bd41ea3edc6446a855306eed34f93b (patch) | |
tree | a2363453f0073ccaf7defddde7ac703a2a71bbd9 | |
parent | 4f9d03251b9d202ebce805757360ef0fac5eb74e (diff) |
perf annotate: Parse call targets earlier
No need to do it everytime the user presses enter/-> on a call
instruction.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
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-ybgss44m5ycry8mk7b1qdbre@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 10 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 18 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 1 |
3 files changed, 23 insertions, 6 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index bdbb54fd05ae..46ef966ccc5b 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -266,11 +266,10 @@ static bool annotate_browser__callq(struct annotate_browser *browser, | |||
266 | struct symbol *target; | 266 | struct symbol *target; |
267 | u64 ip; | 267 | u64 ip; |
268 | 268 | ||
269 | if (strcmp(dl->name, "callq")) | 269 | if (!ins__is_call(dl->ins)) |
270 | return false; | 270 | return false; |
271 | 271 | ||
272 | ip = strtoull(dl->operands, NULL, 16); | 272 | ip = ms->map->map_ip(ms->map, dl->target); |
273 | ip = ms->map->map_ip(ms->map, ip); | ||
274 | target = map__find_symbol(ms->map, ip, NULL); | 273 | target = map__find_symbol(ms->map, ip, NULL); |
275 | if (target == NULL) { | 274 | if (target == NULL) { |
276 | ui_helpline__puts("The called function was not found."); | 275 | ui_helpline__puts("The called function was not found."); |
@@ -318,7 +317,7 @@ static bool annotate_browser__jump(struct annotate_browser *browser) | |||
318 | struct disasm_line *dl = browser->selection; | 317 | struct disasm_line *dl = browser->selection; |
319 | s64 idx; | 318 | s64 idx; |
320 | 319 | ||
321 | if (!dl->ins || !ins__is_jump(dl->ins)) | 320 | if (!ins__is_jump(dl->ins)) |
322 | return false; | 321 | return false; |
323 | 322 | ||
324 | dl = annotate_browser__find_offset(browser, dl->target, &idx); | 323 | dl = annotate_browser__find_offset(browser, dl->target, &idx); |
@@ -556,7 +555,8 @@ show_help: | |||
556 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); | 555 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); |
557 | else if (self->selection->offset == -1) | 556 | else if (self->selection->offset == -1) |
558 | ui_helpline__puts("Actions are only available for assembly lines."); | 557 | ui_helpline__puts("Actions are only available for assembly lines."); |
559 | else if (!(annotate_browser__jump(self) || | 558 | else if (!self->selection->ins || |
559 | !(annotate_browser__jump(self) || | ||
560 | annotate_browser__callq(self, evidx, timer, arg, delay_secs))) | 560 | annotate_browser__callq(self, evidx, timer, arg, delay_secs))) |
561 | ui_helpline__puts("Actions are only available for the 'callq' and jump instructions."); | 561 | ui_helpline__puts("Actions are only available for the 'callq' and jump instructions."); |
562 | continue; | 562 | continue; |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4ee2c07924bc..a4296fdd9a68 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -18,6 +18,21 @@ | |||
18 | 18 | ||
19 | const char *disassembler_style; | 19 | const char *disassembler_style; |
20 | 20 | ||
21 | static int call_ops__parse_target(const char *operands, u64 *target) | ||
22 | { | ||
23 | *target = strtoull(operands, NULL, 16); | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static struct ins_ops call_ops = { | ||
28 | .parse_target = call_ops__parse_target, | ||
29 | }; | ||
30 | |||
31 | bool ins__is_call(const struct ins *ins) | ||
32 | { | ||
33 | return ins->ops == &call_ops; | ||
34 | } | ||
35 | |||
21 | static int jump_ops__parse_target(const char *operands, u64 *target) | 36 | static int jump_ops__parse_target(const char *operands, u64 *target) |
22 | { | 37 | { |
23 | const char *s = strchr(operands, '+'); | 38 | const char *s = strchr(operands, '+'); |
@@ -38,11 +53,12 @@ bool ins__is_jump(const struct ins *ins) | |||
38 | return ins->ops == &jump_ops; | 53 | return ins->ops == &jump_ops; |
39 | } | 54 | } |
40 | 55 | ||
41 | |||
42 | /* | 56 | /* |
43 | * Must be sorted by name! | 57 | * Must be sorted by name! |
44 | */ | 58 | */ |
45 | static struct ins instructions[] = { | 59 | static struct ins instructions[] = { |
60 | { .name = "call", .ops = &call_ops, }, | ||
61 | { .name = "callq", .ops = &call_ops, }, | ||
46 | { .name = "ja", .ops = &jump_ops, }, | 62 | { .name = "ja", .ops = &jump_ops, }, |
47 | { .name = "je", .ops = &jump_ops, }, | 63 | { .name = "je", .ops = &jump_ops, }, |
48 | { .name = "jmp", .ops = &jump_ops, }, | 64 | { .name = "jmp", .ops = &jump_ops, }, |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 934c6fe3a91b..a2105f204a42 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -17,6 +17,7 @@ struct ins { | |||
17 | }; | 17 | }; |
18 | 18 | ||
19 | bool ins__is_jump(const struct ins *ins); | 19 | bool ins__is_jump(const struct ins *ins); |
20 | bool ins__is_call(const struct ins *ins); | ||
20 | 21 | ||
21 | struct disasm_line { | 22 | struct disasm_line { |
22 | struct list_head node; | 23 | struct list_head node; |