diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-05-30 03:02:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-05-30 03:02:00 -0400 |
commit | 59cd358a7a5b2f6b61faa01dae6cfda3830ac62a (patch) | |
tree | 1cefdeac3112e790afc275d9e57cd56674084fa4 /tools/perf/ui/browsers/annotate.c | |
parent | 55b78e34b12d07b8ab7d7732fd24892df8eea5c7 (diff) | |
parent | 05e8b0804ec423a440882e7adecb36e7ac43e56f (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Annotation fixes/improvements from Arnaldo Carvalho de Melo:
. Make the annotatation toggles (hide_src_code, jump_arrows, use_offset, etc)
global so that navigation doesn't resets them on new annotations.
. Introduce an '[annotate]' config file section to allow permanent changes
to the annotate browser defaults.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 258 |
1 files changed, 169 insertions, 89 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index aaf36ce0b6fe..4deea6aaf927 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -19,6 +19,16 @@ struct browser_disasm_line { | |||
19 | int jump_sources; | 19 | int jump_sources; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static struct annotate_browser_opt { | ||
23 | bool hide_src_code, | ||
24 | use_offset, | ||
25 | jump_arrows, | ||
26 | show_nr_jumps; | ||
27 | } annotate_browser__opts = { | ||
28 | .use_offset = true, | ||
29 | .jump_arrows = true, | ||
30 | }; | ||
31 | |||
22 | struct annotate_browser { | 32 | struct annotate_browser { |
23 | struct ui_browser b; | 33 | struct ui_browser b; |
24 | struct rb_root entries; | 34 | struct rb_root entries; |
@@ -30,10 +40,6 @@ struct annotate_browser { | |||
30 | int nr_entries; | 40 | int nr_entries; |
31 | int max_jump_sources; | 41 | int max_jump_sources; |
32 | int nr_jumps; | 42 | int nr_jumps; |
33 | bool hide_src_code; | ||
34 | bool use_offset; | ||
35 | bool jump_arrows; | ||
36 | bool show_nr_jumps; | ||
37 | bool searching_backwards; | 43 | bool searching_backwards; |
38 | u8 addr_width; | 44 | u8 addr_width; |
39 | u8 jumps_width; | 45 | u8 jumps_width; |
@@ -48,11 +54,9 @@ static inline struct browser_disasm_line *disasm_line__browser(struct disasm_lin | |||
48 | return (struct browser_disasm_line *)(dl + 1); | 54 | return (struct browser_disasm_line *)(dl + 1); |
49 | } | 55 | } |
50 | 56 | ||
51 | static bool disasm_line__filter(struct ui_browser *browser, void *entry) | 57 | static bool disasm_line__filter(struct ui_browser *browser __used, void *entry) |
52 | { | 58 | { |
53 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | 59 | if (annotate_browser__opts.hide_src_code) { |
54 | |||
55 | if (ab->hide_src_code) { | ||
56 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); | 60 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); |
57 | return dl->offset == -1; | 61 | return dl->offset == -1; |
58 | } | 62 | } |
@@ -79,30 +83,30 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br | |||
79 | return ui_browser__set_color(&browser->b, color); | 83 | return ui_browser__set_color(&browser->b, color); |
80 | } | 84 | } |
81 | 85 | ||
82 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) | 86 | static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) |
83 | { | 87 | { |
84 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); | 88 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); |
85 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); | 89 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); |
86 | struct browser_disasm_line *bdl = disasm_line__browser(dl); | 90 | struct browser_disasm_line *bdl = disasm_line__browser(dl); |
87 | bool current_entry = ui_browser__is_current_entry(self, row); | 91 | bool current_entry = ui_browser__is_current_entry(browser, row); |
88 | bool change_color = (!ab->hide_src_code && | 92 | bool change_color = (!annotate_browser__opts.hide_src_code && |
89 | (!current_entry || (self->use_navkeypressed && | 93 | (!current_entry || (browser->use_navkeypressed && |
90 | !self->navkeypressed))); | 94 | !browser->navkeypressed))); |
91 | int width = self->width, printed; | 95 | int width = browser->width, printed; |
92 | char bf[256]; | 96 | char bf[256]; |
93 | 97 | ||
94 | if (dl->offset != -1 && bdl->percent != 0.0) { | 98 | if (dl->offset != -1 && bdl->percent != 0.0) { |
95 | ui_browser__set_percent_color(self, bdl->percent, current_entry); | 99 | ui_browser__set_percent_color(browser, bdl->percent, current_entry); |
96 | slsmg_printf("%6.2f ", bdl->percent); | 100 | slsmg_printf("%6.2f ", bdl->percent); |
97 | } else { | 101 | } else { |
98 | ui_browser__set_percent_color(self, 0, current_entry); | 102 | ui_browser__set_percent_color(browser, 0, current_entry); |
99 | slsmg_write_nstring(" ", 7); | 103 | slsmg_write_nstring(" ", 7); |
100 | } | 104 | } |
101 | 105 | ||
102 | SLsmg_write_char(' '); | 106 | SLsmg_write_char(' '); |
103 | 107 | ||
104 | /* The scroll bar isn't being used */ | 108 | /* The scroll bar isn't being used */ |
105 | if (!self->navkeypressed) | 109 | if (!browser->navkeypressed) |
106 | width += 1; | 110 | width += 1; |
107 | 111 | ||
108 | if (!*dl->line) | 112 | if (!*dl->line) |
@@ -116,14 +120,14 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
116 | u64 addr = dl->offset; | 120 | u64 addr = dl->offset; |
117 | int color = -1; | 121 | int color = -1; |
118 | 122 | ||
119 | if (!ab->use_offset) | 123 | if (!annotate_browser__opts.use_offset) |
120 | addr += ab->start; | 124 | addr += ab->start; |
121 | 125 | ||
122 | if (!ab->use_offset) { | 126 | if (!annotate_browser__opts.use_offset) { |
123 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); | 127 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); |
124 | } else { | 128 | } else { |
125 | if (bdl->jump_sources) { | 129 | if (bdl->jump_sources) { |
126 | if (ab->show_nr_jumps) { | 130 | if (annotate_browser__opts.show_nr_jumps) { |
127 | int prev; | 131 | int prev; |
128 | printed = scnprintf(bf, sizeof(bf), "%*d ", | 132 | printed = scnprintf(bf, sizeof(bf), "%*d ", |
129 | ab->jumps_width, | 133 | ab->jumps_width, |
@@ -131,7 +135,7 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
131 | prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, | 135 | prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, |
132 | current_entry); | 136 | current_entry); |
133 | slsmg_write_nstring(bf, printed); | 137 | slsmg_write_nstring(bf, printed); |
134 | ui_browser__set_color(self, prev); | 138 | ui_browser__set_color(browser, prev); |
135 | } | 139 | } |
136 | 140 | ||
137 | printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", | 141 | printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", |
@@ -143,19 +147,19 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
143 | } | 147 | } |
144 | 148 | ||
145 | if (change_color) | 149 | if (change_color) |
146 | color = ui_browser__set_color(self, HE_COLORSET_ADDR); | 150 | color = ui_browser__set_color(browser, HE_COLORSET_ADDR); |
147 | slsmg_write_nstring(bf, printed); | 151 | slsmg_write_nstring(bf, printed); |
148 | if (change_color) | 152 | if (change_color) |
149 | ui_browser__set_color(self, color); | 153 | ui_browser__set_color(browser, color); |
150 | if (dl->ins && dl->ins->ops->scnprintf) { | 154 | if (dl->ins && dl->ins->ops->scnprintf) { |
151 | if (ins__is_jump(dl->ins)) { | 155 | if (ins__is_jump(dl->ins)) { |
152 | bool fwd = dl->ops.target.offset > (u64)dl->offset; | 156 | bool fwd = dl->ops.target.offset > (u64)dl->offset; |
153 | 157 | ||
154 | ui_browser__write_graph(self, fwd ? SLSMG_DARROW_CHAR : | 158 | ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : |
155 | SLSMG_UARROW_CHAR); | 159 | SLSMG_UARROW_CHAR); |
156 | SLsmg_write_char(' '); | 160 | SLsmg_write_char(' '); |
157 | } else if (ins__is_call(dl->ins)) { | 161 | } else if (ins__is_call(dl->ins)) { |
158 | ui_browser__write_graph(self, SLSMG_RARROW_CHAR); | 162 | ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); |
159 | SLsmg_write_char(' '); | 163 | SLsmg_write_char(' '); |
160 | } else { | 164 | } else { |
161 | slsmg_write_nstring(" ", 2); | 165 | slsmg_write_nstring(" ", 2); |
@@ -164,12 +168,12 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
164 | if (strcmp(dl->name, "retq")) { | 168 | if (strcmp(dl->name, "retq")) { |
165 | slsmg_write_nstring(" ", 2); | 169 | slsmg_write_nstring(" ", 2); |
166 | } else { | 170 | } else { |
167 | ui_browser__write_graph(self, SLSMG_LARROW_CHAR); | 171 | ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); |
168 | SLsmg_write_char(' '); | 172 | SLsmg_write_char(' '); |
169 | } | 173 | } |
170 | } | 174 | } |
171 | 175 | ||
172 | disasm_line__scnprintf(dl, bf, sizeof(bf), !ab->use_offset); | 176 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); |
173 | slsmg_write_nstring(bf, width - 10 - printed); | 177 | slsmg_write_nstring(bf, width - 10 - printed); |
174 | } | 178 | } |
175 | 179 | ||
@@ -184,7 +188,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
184 | struct browser_disasm_line *btarget, *bcursor; | 188 | struct browser_disasm_line *btarget, *bcursor; |
185 | unsigned int from, to; | 189 | unsigned int from, to; |
186 | 190 | ||
187 | if (!cursor->ins || !ins__is_jump(cursor->ins) || | 191 | if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) || |
188 | !disasm_line__has_offset(cursor)) | 192 | !disasm_line__has_offset(cursor)) |
189 | return; | 193 | return; |
190 | 194 | ||
@@ -195,7 +199,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
195 | bcursor = disasm_line__browser(cursor); | 199 | bcursor = disasm_line__browser(cursor); |
196 | btarget = disasm_line__browser(target); | 200 | btarget = disasm_line__browser(target); |
197 | 201 | ||
198 | if (ab->hide_src_code) { | 202 | if (annotate_browser__opts.hide_src_code) { |
199 | from = bcursor->idx_asm; | 203 | from = bcursor->idx_asm; |
200 | to = btarget->idx_asm; | 204 | to = btarget->idx_asm; |
201 | } else { | 205 | } else { |
@@ -209,10 +213,9 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
209 | 213 | ||
210 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) | 214 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) |
211 | { | 215 | { |
212 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | ||
213 | int ret = ui_browser__list_head_refresh(browser); | 216 | int ret = ui_browser__list_head_refresh(browser); |
214 | 217 | ||
215 | if (ab->jump_arrows) | 218 | if (annotate_browser__opts.jump_arrows) |
216 | annotate_browser__draw_current_jump(browser); | 219 | annotate_browser__draw_current_jump(browser); |
217 | 220 | ||
218 | ui_browser__set_color(browser, HE_COLORSET_NORMAL); | 221 | ui_browser__set_color(browser, HE_COLORSET_NORMAL); |
@@ -272,27 +275,27 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_l | |||
272 | rb_insert_color(&bdl->rb_node, root); | 275 | rb_insert_color(&bdl->rb_node, root); |
273 | } | 276 | } |
274 | 277 | ||
275 | static void annotate_browser__set_top(struct annotate_browser *self, | 278 | static void annotate_browser__set_top(struct annotate_browser *browser, |
276 | struct disasm_line *pos, u32 idx) | 279 | struct disasm_line *pos, u32 idx) |
277 | { | 280 | { |
278 | unsigned back; | 281 | unsigned back; |
279 | 282 | ||
280 | ui_browser__refresh_dimensions(&self->b); | 283 | ui_browser__refresh_dimensions(&browser->b); |
281 | back = self->b.height / 2; | 284 | back = browser->b.height / 2; |
282 | self->b.top_idx = self->b.index = idx; | 285 | browser->b.top_idx = browser->b.index = idx; |
283 | 286 | ||
284 | while (self->b.top_idx != 0 && back != 0) { | 287 | while (browser->b.top_idx != 0 && back != 0) { |
285 | pos = list_entry(pos->node.prev, struct disasm_line, node); | 288 | pos = list_entry(pos->node.prev, struct disasm_line, node); |
286 | 289 | ||
287 | if (disasm_line__filter(&self->b, &pos->node)) | 290 | if (disasm_line__filter(&browser->b, &pos->node)) |
288 | continue; | 291 | continue; |
289 | 292 | ||
290 | --self->b.top_idx; | 293 | --browser->b.top_idx; |
291 | --back; | 294 | --back; |
292 | } | 295 | } |
293 | 296 | ||
294 | self->b.top = pos; | 297 | browser->b.top = pos; |
295 | self->b.navkeypressed = true; | 298 | browser->b.navkeypressed = true; |
296 | } | 299 | } |
297 | 300 | ||
298 | static void annotate_browser__set_rb_top(struct annotate_browser *browser, | 301 | static void annotate_browser__set_rb_top(struct annotate_browser *browser, |
@@ -305,7 +308,7 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser, | |||
305 | bpos = rb_entry(nd, struct browser_disasm_line, rb_node); | 308 | bpos = rb_entry(nd, struct browser_disasm_line, rb_node); |
306 | pos = ((struct disasm_line *)bpos) - 1; | 309 | pos = ((struct disasm_line *)bpos) - 1; |
307 | idx = bpos->idx; | 310 | idx = bpos->idx; |
308 | if (browser->hide_src_code) | 311 | if (annotate_browser__opts.hide_src_code) |
309 | idx = bpos->idx_asm; | 312 | idx = bpos->idx_asm; |
310 | annotate_browser__set_top(browser, pos, idx); | 313 | annotate_browser__set_top(browser, pos, idx); |
311 | browser->curr_hot = nd; | 314 | browser->curr_hot = nd; |
@@ -347,12 +350,12 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser) | |||
347 | dl = list_entry(browser->b.top, struct disasm_line, node); | 350 | dl = list_entry(browser->b.top, struct disasm_line, node); |
348 | bdl = disasm_line__browser(dl); | 351 | bdl = disasm_line__browser(dl); |
349 | 352 | ||
350 | if (browser->hide_src_code) { | 353 | if (annotate_browser__opts.hide_src_code) { |
351 | if (bdl->idx_asm < offset) | 354 | if (bdl->idx_asm < offset) |
352 | offset = bdl->idx; | 355 | offset = bdl->idx; |
353 | 356 | ||
354 | browser->b.nr_entries = browser->nr_entries; | 357 | browser->b.nr_entries = browser->nr_entries; |
355 | browser->hide_src_code = false; | 358 | annotate_browser__opts.hide_src_code = false; |
356 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | 359 | browser->b.seek(&browser->b, -offset, SEEK_CUR); |
357 | browser->b.top_idx = bdl->idx - offset; | 360 | browser->b.top_idx = bdl->idx - offset; |
358 | browser->b.index = bdl->idx; | 361 | browser->b.index = bdl->idx; |
@@ -367,7 +370,7 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser) | |||
367 | offset = bdl->idx_asm; | 370 | offset = bdl->idx_asm; |
368 | 371 | ||
369 | browser->b.nr_entries = browser->nr_asm_entries; | 372 | browser->b.nr_entries = browser->nr_asm_entries; |
370 | browser->hide_src_code = true; | 373 | annotate_browser__opts.hide_src_code = true; |
371 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | 374 | browser->b.seek(&browser->b, -offset, SEEK_CUR); |
372 | browser->b.top_idx = bdl->idx_asm - offset; | 375 | browser->b.top_idx = bdl->idx_asm - offset; |
373 | browser->b.index = bdl->idx_asm; | 376 | browser->b.index = bdl->idx_asm; |
@@ -376,6 +379,12 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser) | |||
376 | return true; | 379 | return true; |
377 | } | 380 | } |
378 | 381 | ||
382 | static void annotate_browser__init_asm_mode(struct annotate_browser *browser) | ||
383 | { | ||
384 | ui_browser__reset_index(&browser->b); | ||
385 | browser->b.nr_entries = browser->nr_asm_entries; | ||
386 | } | ||
387 | |||
379 | static bool annotate_browser__callq(struct annotate_browser *browser, | 388 | static bool annotate_browser__callq(struct annotate_browser *browser, |
380 | int evidx, void (*timer)(void *arg), | 389 | int evidx, void (*timer)(void *arg), |
381 | void *arg, int delay_secs) | 390 | void *arg, int delay_secs) |
@@ -578,33 +587,46 @@ bool annotate_browser__continue_search_reverse(struct annotate_browser *browser, | |||
578 | return __annotate_browser__search_reverse(browser); | 587 | return __annotate_browser__search_reverse(browser); |
579 | } | 588 | } |
580 | 589 | ||
581 | static int annotate_browser__run(struct annotate_browser *self, int evidx, | 590 | static void annotate_browser__update_addr_width(struct annotate_browser *browser) |
591 | { | ||
592 | if (annotate_browser__opts.use_offset) | ||
593 | browser->target_width = browser->min_addr_width; | ||
594 | else | ||
595 | browser->target_width = browser->max_addr_width; | ||
596 | |||
597 | browser->addr_width = browser->target_width; | ||
598 | |||
599 | if (annotate_browser__opts.show_nr_jumps) | ||
600 | browser->addr_width += browser->jumps_width + 1; | ||
601 | } | ||
602 | |||
603 | static int annotate_browser__run(struct annotate_browser *browser, int evidx, | ||
582 | void(*timer)(void *arg), | 604 | void(*timer)(void *arg), |
583 | void *arg, int delay_secs) | 605 | void *arg, int delay_secs) |
584 | { | 606 | { |
585 | struct rb_node *nd = NULL; | 607 | struct rb_node *nd = NULL; |
586 | struct map_symbol *ms = self->b.priv; | 608 | struct map_symbol *ms = browser->b.priv; |
587 | struct symbol *sym = ms->sym; | 609 | struct symbol *sym = ms->sym; |
588 | const char *help = "Press 'h' for help on key bindings"; | 610 | const char *help = "Press 'h' for help on key bindings"; |
589 | int key; | 611 | int key; |
590 | 612 | ||
591 | if (ui_browser__show(&self->b, sym->name, help) < 0) | 613 | if (ui_browser__show(&browser->b, sym->name, help) < 0) |
592 | return -1; | 614 | return -1; |
593 | 615 | ||
594 | annotate_browser__calc_percent(self, evidx); | 616 | annotate_browser__calc_percent(browser, evidx); |
595 | 617 | ||
596 | if (self->curr_hot) { | 618 | if (browser->curr_hot) { |
597 | annotate_browser__set_rb_top(self, self->curr_hot); | 619 | annotate_browser__set_rb_top(browser, browser->curr_hot); |
598 | self->b.navkeypressed = false; | 620 | browser->b.navkeypressed = false; |
599 | } | 621 | } |
600 | 622 | ||
601 | nd = self->curr_hot; | 623 | nd = browser->curr_hot; |
602 | 624 | ||
603 | while (1) { | 625 | while (1) { |
604 | key = ui_browser__run(&self->b, delay_secs); | 626 | key = ui_browser__run(&browser->b, delay_secs); |
605 | 627 | ||
606 | if (delay_secs != 0) { | 628 | if (delay_secs != 0) { |
607 | annotate_browser__calc_percent(self, evidx); | 629 | annotate_browser__calc_percent(browser, evidx); |
608 | /* | 630 | /* |
609 | * Current line focus got out of the list of most active | 631 | * Current line focus got out of the list of most active |
610 | * lines, NULL it so that if TAB|UNTAB is pressed, we | 632 | * lines, NULL it so that if TAB|UNTAB is pressed, we |
@@ -626,21 +648,21 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
626 | if (nd != NULL) { | 648 | if (nd != NULL) { |
627 | nd = rb_prev(nd); | 649 | nd = rb_prev(nd); |
628 | if (nd == NULL) | 650 | if (nd == NULL) |
629 | nd = rb_last(&self->entries); | 651 | nd = rb_last(&browser->entries); |
630 | } else | 652 | } else |
631 | nd = self->curr_hot; | 653 | nd = browser->curr_hot; |
632 | break; | 654 | break; |
633 | case K_UNTAB: | 655 | case K_UNTAB: |
634 | if (nd != NULL) | 656 | if (nd != NULL) |
635 | nd = rb_next(nd); | 657 | nd = rb_next(nd); |
636 | if (nd == NULL) | 658 | if (nd == NULL) |
637 | nd = rb_first(&self->entries); | 659 | nd = rb_first(&browser->entries); |
638 | else | 660 | else |
639 | nd = self->curr_hot; | 661 | nd = browser->curr_hot; |
640 | break; | 662 | break; |
641 | case K_F1: | 663 | case K_F1: |
642 | case 'h': | 664 | case 'h': |
643 | ui_browser__help_window(&self->b, | 665 | ui_browser__help_window(&browser->b, |
644 | "UP/DOWN/PGUP\n" | 666 | "UP/DOWN/PGUP\n" |
645 | "PGDN/SPACE Navigate\n" | 667 | "PGDN/SPACE Navigate\n" |
646 | "q/ESC/CTRL+C Exit\n\n" | 668 | "q/ESC/CTRL+C Exit\n\n" |
@@ -656,57 +678,62 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
656 | "? Search previous string\n"); | 678 | "? Search previous string\n"); |
657 | continue; | 679 | continue; |
658 | case 'H': | 680 | case 'H': |
659 | nd = self->curr_hot; | 681 | nd = browser->curr_hot; |
660 | break; | 682 | break; |
661 | case 's': | 683 | case 's': |
662 | if (annotate_browser__toggle_source(self)) | 684 | if (annotate_browser__toggle_source(browser)) |
663 | ui_helpline__puts(help); | 685 | ui_helpline__puts(help); |
664 | continue; | 686 | continue; |
665 | case 'o': | 687 | case 'o': |
666 | self->use_offset = !self->use_offset; | 688 | annotate_browser__opts.use_offset = !annotate_browser__opts.use_offset; |
667 | if (self->use_offset) | 689 | annotate_browser__update_addr_width(browser); |
668 | self->target_width = self->min_addr_width; | ||
669 | else | ||
670 | self->target_width = self->max_addr_width; | ||
671 | update_addr_width: | ||
672 | self->addr_width = self->target_width; | ||
673 | if (self->show_nr_jumps) | ||
674 | self->addr_width += self->jumps_width + 1; | ||
675 | continue; | 690 | continue; |
676 | case 'j': | 691 | case 'j': |
677 | self->jump_arrows = !self->jump_arrows; | 692 | annotate_browser__opts.jump_arrows = !annotate_browser__opts.jump_arrows; |
678 | continue; | 693 | continue; |
679 | case 'J': | 694 | case 'J': |
680 | self->show_nr_jumps = !self->show_nr_jumps; | 695 | annotate_browser__opts.show_nr_jumps = !annotate_browser__opts.show_nr_jumps; |
681 | goto update_addr_width; | 696 | annotate_browser__update_addr_width(browser); |
697 | continue; | ||
682 | case '/': | 698 | case '/': |
683 | if (annotate_browser__search(self, delay_secs)) { | 699 | if (annotate_browser__search(browser, delay_secs)) { |
684 | show_help: | 700 | show_help: |
685 | ui_helpline__puts(help); | 701 | ui_helpline__puts(help); |
686 | } | 702 | } |
687 | continue; | 703 | continue; |
688 | case 'n': | 704 | case 'n': |
689 | if (self->searching_backwards ? | 705 | if (browser->searching_backwards ? |
690 | annotate_browser__continue_search_reverse(self, delay_secs) : | 706 | annotate_browser__continue_search_reverse(browser, delay_secs) : |
691 | annotate_browser__continue_search(self, delay_secs)) | 707 | annotate_browser__continue_search(browser, delay_secs)) |
692 | goto show_help; | 708 | goto show_help; |
693 | continue; | 709 | continue; |
694 | case '?': | 710 | case '?': |
695 | if (annotate_browser__search_reverse(self, delay_secs)) | 711 | if (annotate_browser__search_reverse(browser, delay_secs)) |
696 | goto show_help; | 712 | goto show_help; |
697 | continue; | 713 | continue; |
714 | case 'D': { | ||
715 | static int seq; | ||
716 | ui_helpline__pop(); | ||
717 | ui_helpline__fpush("%d: nr_ent=%d, height=%d, idx=%d, top_idx=%d, nr_asm_entries=%d", | ||
718 | seq++, browser->b.nr_entries, | ||
719 | browser->b.height, | ||
720 | browser->b.index, | ||
721 | browser->b.top_idx, | ||
722 | browser->nr_asm_entries); | ||
723 | } | ||
724 | continue; | ||
698 | case K_ENTER: | 725 | case K_ENTER: |
699 | case K_RIGHT: | 726 | case K_RIGHT: |
700 | if (self->selection == NULL) | 727 | if (browser->selection == NULL) |
701 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); | 728 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); |
702 | else if (self->selection->offset == -1) | 729 | else if (browser->selection->offset == -1) |
703 | ui_helpline__puts("Actions are only available for assembly lines."); | 730 | ui_helpline__puts("Actions are only available for assembly lines."); |
704 | else if (!self->selection->ins) { | 731 | else if (!browser->selection->ins) { |
705 | if (strcmp(self->selection->name, "retq")) | 732 | if (strcmp(browser->selection->name, "retq")) |
706 | goto show_sup_ins; | 733 | goto show_sup_ins; |
707 | goto out; | 734 | goto out; |
708 | } else if (!(annotate_browser__jump(self) || | 735 | } else if (!(annotate_browser__jump(browser) || |
709 | annotate_browser__callq(self, evidx, timer, arg, delay_secs))) { | 736 | annotate_browser__callq(browser, evidx, timer, arg, delay_secs))) { |
710 | show_sup_ins: | 737 | show_sup_ins: |
711 | ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); | 738 | ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); |
712 | } | 739 | } |
@@ -721,10 +748,10 @@ show_sup_ins: | |||
721 | } | 748 | } |
722 | 749 | ||
723 | if (nd != NULL) | 750 | if (nd != NULL) |
724 | annotate_browser__set_rb_top(self, nd); | 751 | annotate_browser__set_rb_top(browser, nd); |
725 | } | 752 | } |
726 | out: | 753 | out: |
727 | ui_browser__hide(&self->b); | 754 | ui_browser__hide(&browser->b); |
728 | return key; | 755 | return key; |
729 | } | 756 | } |
730 | 757 | ||
@@ -801,8 +828,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
801 | .priv = &ms, | 828 | .priv = &ms, |
802 | .use_navkeypressed = true, | 829 | .use_navkeypressed = true, |
803 | }, | 830 | }, |
804 | .use_offset = true, | ||
805 | .jump_arrows = true, | ||
806 | }; | 831 | }; |
807 | int ret = -1; | 832 | int ret = -1; |
808 | 833 | ||
@@ -859,6 +884,12 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
859 | browser.b.nr_entries = browser.nr_entries; | 884 | browser.b.nr_entries = browser.nr_entries; |
860 | browser.b.entries = ¬es->src->source, | 885 | browser.b.entries = ¬es->src->source, |
861 | browser.b.width += 18; /* Percentage */ | 886 | browser.b.width += 18; /* Percentage */ |
887 | |||
888 | if (annotate_browser__opts.hide_src_code) | ||
889 | annotate_browser__init_asm_mode(&browser); | ||
890 | |||
891 | annotate_browser__update_addr_width(&browser); | ||
892 | |||
862 | ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs); | 893 | ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs); |
863 | list_for_each_entry_safe(pos, n, ¬es->src->source, node) { | 894 | list_for_each_entry_safe(pos, n, ¬es->src->source, node) { |
864 | list_del(&pos->node); | 895 | list_del(&pos->node); |
@@ -869,3 +900,52 @@ out_free_offsets: | |||
869 | free(browser.offsets); | 900 | free(browser.offsets); |
870 | return ret; | 901 | return ret; |
871 | } | 902 | } |
903 | |||
904 | #define ANNOTATE_CFG(n) \ | ||
905 | { .name = #n, .value = &annotate_browser__opts.n, } | ||
906 | |||
907 | /* | ||
908 | * Keep the entries sorted, they are bsearch'ed | ||
909 | */ | ||
910 | static struct annotate__config { | ||
911 | const char *name; | ||
912 | bool *value; | ||
913 | } annotate__configs[] = { | ||
914 | ANNOTATE_CFG(hide_src_code), | ||
915 | ANNOTATE_CFG(jump_arrows), | ||
916 | ANNOTATE_CFG(show_nr_jumps), | ||
917 | ANNOTATE_CFG(use_offset), | ||
918 | }; | ||
919 | |||
920 | #undef ANNOTATE_CFG | ||
921 | |||
922 | static int annotate_config__cmp(const void *name, const void *cfgp) | ||
923 | { | ||
924 | const struct annotate__config *cfg = cfgp; | ||
925 | |||
926 | return strcmp(name, cfg->name); | ||
927 | } | ||
928 | |||
929 | static int annotate__config(const char *var, const char *value, void *data __used) | ||
930 | { | ||
931 | struct annotate__config *cfg; | ||
932 | const char *name; | ||
933 | |||
934 | if (prefixcmp(var, "annotate.") != 0) | ||
935 | return 0; | ||
936 | |||
937 | name = var + 9; | ||
938 | cfg = bsearch(name, annotate__configs, ARRAY_SIZE(annotate__configs), | ||
939 | sizeof(struct annotate__config), annotate_config__cmp); | ||
940 | |||
941 | if (cfg == NULL) | ||
942 | return -1; | ||
943 | |||
944 | *cfg->value = perf_config_bool(name, value); | ||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | void annotate_browser__init(void) | ||
949 | { | ||
950 | perf_config(annotate__config, NULL); | ||
951 | } | ||