diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 399 |
1 files changed, 197 insertions, 202 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 8f7f59d1a2b5..286427975112 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -25,16 +25,10 @@ struct disasm_line_samples { | |||
25 | #define IPC_WIDTH 6 | 25 | #define IPC_WIDTH 6 |
26 | #define CYCLES_WIDTH 6 | 26 | #define CYCLES_WIDTH 6 |
27 | 27 | ||
28 | struct browser_disasm_line { | 28 | struct browser_line { |
29 | struct rb_node rb_node; | 29 | u32 idx; |
30 | u32 idx; | 30 | int idx_asm; |
31 | int idx_asm; | 31 | int jump_sources; |
32 | int jump_sources; | ||
33 | /* | ||
34 | * actual length of this array is saved on the nr_events field | ||
35 | * of the struct annotate_browser | ||
36 | */ | ||
37 | struct disasm_line_samples samples[1]; | ||
38 | }; | 32 | }; |
39 | 33 | ||
40 | static struct annotate_browser_opt { | 34 | static struct annotate_browser_opt { |
@@ -53,39 +47,43 @@ static struct annotate_browser_opt { | |||
53 | struct arch; | 47 | struct arch; |
54 | 48 | ||
55 | struct annotate_browser { | 49 | struct annotate_browser { |
56 | struct ui_browser b; | 50 | struct ui_browser b; |
57 | struct rb_root entries; | 51 | struct rb_root entries; |
58 | struct rb_node *curr_hot; | 52 | struct rb_node *curr_hot; |
59 | struct disasm_line *selection; | 53 | struct annotation_line *selection; |
60 | struct disasm_line **offsets; | 54 | struct annotation_line **offsets; |
61 | struct arch *arch; | 55 | struct arch *arch; |
62 | int nr_events; | 56 | int nr_events; |
63 | u64 start; | 57 | u64 start; |
64 | int nr_asm_entries; | 58 | int nr_asm_entries; |
65 | int nr_entries; | 59 | int nr_entries; |
66 | int max_jump_sources; | 60 | int max_jump_sources; |
67 | int nr_jumps; | 61 | int nr_jumps; |
68 | bool searching_backwards; | 62 | bool searching_backwards; |
69 | bool have_cycles; | 63 | bool have_cycles; |
70 | u8 addr_width; | 64 | u8 addr_width; |
71 | u8 jumps_width; | 65 | u8 jumps_width; |
72 | u8 target_width; | 66 | u8 target_width; |
73 | u8 min_addr_width; | 67 | u8 min_addr_width; |
74 | u8 max_addr_width; | 68 | u8 max_addr_width; |
75 | char search_bf[128]; | 69 | char search_bf[128]; |
76 | }; | 70 | }; |
77 | 71 | ||
78 | static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl) | 72 | static inline struct browser_line *browser_line(struct annotation_line *al) |
79 | { | 73 | { |
80 | return (struct browser_disasm_line *)(dl + 1); | 74 | void *ptr = al; |
75 | |||
76 | ptr = container_of(al, struct disasm_line, al); | ||
77 | return ptr - sizeof(struct browser_line); | ||
81 | } | 78 | } |
82 | 79 | ||
83 | static bool disasm_line__filter(struct ui_browser *browser __maybe_unused, | 80 | static bool disasm_line__filter(struct ui_browser *browser __maybe_unused, |
84 | void *entry) | 81 | void *entry) |
85 | { | 82 | { |
86 | if (annotate_browser__opts.hide_src_code) { | 83 | if (annotate_browser__opts.hide_src_code) { |
87 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); | 84 | struct annotation_line *al = list_entry(entry, struct annotation_line, node); |
88 | return dl->offset == -1; | 85 | |
86 | return al->offset == -1; | ||
89 | } | 87 | } |
90 | 88 | ||
91 | return false; | 89 | return false; |
@@ -120,11 +118,37 @@ static int annotate_browser__cycles_width(struct annotate_browser *ab) | |||
120 | return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; | 118 | return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; |
121 | } | 119 | } |
122 | 120 | ||
121 | static void disasm_line__write(struct disasm_line *dl, struct ui_browser *browser, | ||
122 | char *bf, size_t size) | ||
123 | { | ||
124 | if (dl->ins.ops && dl->ins.ops->scnprintf) { | ||
125 | if (ins__is_jump(&dl->ins)) { | ||
126 | bool fwd = dl->ops.target.offset > dl->al.offset; | ||
127 | |||
128 | ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : | ||
129 | SLSMG_UARROW_CHAR); | ||
130 | SLsmg_write_char(' '); | ||
131 | } else if (ins__is_call(&dl->ins)) { | ||
132 | ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); | ||
133 | SLsmg_write_char(' '); | ||
134 | } else if (ins__is_ret(&dl->ins)) { | ||
135 | ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); | ||
136 | SLsmg_write_char(' '); | ||
137 | } else { | ||
138 | ui_browser__write_nstring(browser, " ", 2); | ||
139 | } | ||
140 | } else { | ||
141 | ui_browser__write_nstring(browser, " ", 2); | ||
142 | } | ||
143 | |||
144 | disasm_line__scnprintf(dl, bf, size, !annotate_browser__opts.use_offset); | ||
145 | } | ||
146 | |||
123 | static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) | 147 | static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) |
124 | { | 148 | { |
125 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | 149 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); |
126 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); | 150 | struct annotation_line *al = list_entry(entry, struct annotation_line, node); |
127 | struct browser_disasm_line *bdl = disasm_line__browser(dl); | 151 | struct browser_line *bl = browser_line(al); |
128 | bool current_entry = ui_browser__is_current_entry(browser, row); | 152 | bool current_entry = ui_browser__is_current_entry(browser, row); |
129 | bool change_color = (!annotate_browser__opts.hide_src_code && | 153 | bool change_color = (!annotate_browser__opts.hide_src_code && |
130 | (!current_entry || (browser->use_navkeypressed && | 154 | (!current_entry || (browser->use_navkeypressed && |
@@ -137,32 +161,32 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
137 | bool show_title = false; | 161 | bool show_title = false; |
138 | 162 | ||
139 | for (i = 0; i < ab->nr_events; i++) { | 163 | for (i = 0; i < ab->nr_events; i++) { |
140 | if (bdl->samples[i].percent > percent_max) | 164 | if (al->samples[i].percent > percent_max) |
141 | percent_max = bdl->samples[i].percent; | 165 | percent_max = al->samples[i].percent; |
142 | } | 166 | } |
143 | 167 | ||
144 | if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) { | 168 | if ((row == 0) && (al->offset == -1 || percent_max == 0.0)) { |
145 | if (ab->have_cycles) { | 169 | if (ab->have_cycles) { |
146 | if (dl->ipc == 0.0 && dl->cycles == 0) | 170 | if (al->ipc == 0.0 && al->cycles == 0) |
147 | show_title = true; | 171 | show_title = true; |
148 | } else | 172 | } else |
149 | show_title = true; | 173 | show_title = true; |
150 | } | 174 | } |
151 | 175 | ||
152 | if (dl->offset != -1 && percent_max != 0.0) { | 176 | if (al->offset != -1 && percent_max != 0.0) { |
153 | for (i = 0; i < ab->nr_events; i++) { | 177 | for (i = 0; i < ab->nr_events; i++) { |
154 | ui_browser__set_percent_color(browser, | 178 | ui_browser__set_percent_color(browser, |
155 | bdl->samples[i].percent, | 179 | al->samples[i].percent, |
156 | current_entry); | 180 | current_entry); |
157 | if (annotate_browser__opts.show_total_period) { | 181 | if (annotate_browser__opts.show_total_period) { |
158 | ui_browser__printf(browser, "%11" PRIu64 " ", | 182 | ui_browser__printf(browser, "%11" PRIu64 " ", |
159 | bdl->samples[i].he.period); | 183 | al->samples[i].he.period); |
160 | } else if (annotate_browser__opts.show_nr_samples) { | 184 | } else if (annotate_browser__opts.show_nr_samples) { |
161 | ui_browser__printf(browser, "%6" PRIu64 " ", | 185 | ui_browser__printf(browser, "%6" PRIu64 " ", |
162 | bdl->samples[i].he.nr_samples); | 186 | al->samples[i].he.nr_samples); |
163 | } else { | 187 | } else { |
164 | ui_browser__printf(browser, "%6.2f ", | 188 | ui_browser__printf(browser, "%6.2f ", |
165 | bdl->samples[i].percent); | 189 | al->samples[i].percent); |
166 | } | 190 | } |
167 | } | 191 | } |
168 | } else { | 192 | } else { |
@@ -177,16 +201,16 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
177 | } | 201 | } |
178 | } | 202 | } |
179 | if (ab->have_cycles) { | 203 | if (ab->have_cycles) { |
180 | if (dl->ipc) | 204 | if (al->ipc) |
181 | ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); | 205 | ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, al->ipc); |
182 | else if (!show_title) | 206 | else if (!show_title) |
183 | ui_browser__write_nstring(browser, " ", IPC_WIDTH); | 207 | ui_browser__write_nstring(browser, " ", IPC_WIDTH); |
184 | else | 208 | else |
185 | ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC"); | 209 | ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC"); |
186 | 210 | ||
187 | if (dl->cycles) | 211 | if (al->cycles) |
188 | ui_browser__printf(browser, "%*" PRIu64 " ", | 212 | ui_browser__printf(browser, "%*" PRIu64 " ", |
189 | CYCLES_WIDTH - 1, dl->cycles); | 213 | CYCLES_WIDTH - 1, al->cycles); |
190 | else if (!show_title) | 214 | else if (!show_title) |
191 | ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); | 215 | ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); |
192 | else | 216 | else |
@@ -199,19 +223,19 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
199 | if (!browser->navkeypressed) | 223 | if (!browser->navkeypressed) |
200 | width += 1; | 224 | width += 1; |
201 | 225 | ||
202 | if (!*dl->line) | 226 | if (!*al->line) |
203 | ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); | 227 | ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); |
204 | else if (dl->offset == -1) { | 228 | else if (al->offset == -1) { |
205 | if (dl->line_nr && annotate_browser__opts.show_linenr) | 229 | if (al->line_nr && annotate_browser__opts.show_linenr) |
206 | printed = scnprintf(bf, sizeof(bf), "%-*d ", | 230 | printed = scnprintf(bf, sizeof(bf), "%-*d ", |
207 | ab->addr_width + 1, dl->line_nr); | 231 | ab->addr_width + 1, al->line_nr); |
208 | else | 232 | else |
209 | printed = scnprintf(bf, sizeof(bf), "%*s ", | 233 | printed = scnprintf(bf, sizeof(bf), "%*s ", |
210 | ab->addr_width, " "); | 234 | ab->addr_width, " "); |
211 | ui_browser__write_nstring(browser, bf, printed); | 235 | ui_browser__write_nstring(browser, bf, printed); |
212 | ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1); | 236 | ui_browser__write_nstring(browser, al->line, width - printed - pcnt_width - cycles_width + 1); |
213 | } else { | 237 | } else { |
214 | u64 addr = dl->offset; | 238 | u64 addr = al->offset; |
215 | int color = -1; | 239 | int color = -1; |
216 | 240 | ||
217 | if (!annotate_browser__opts.use_offset) | 241 | if (!annotate_browser__opts.use_offset) |
@@ -220,13 +244,13 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
220 | if (!annotate_browser__opts.use_offset) { | 244 | if (!annotate_browser__opts.use_offset) { |
221 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); | 245 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); |
222 | } else { | 246 | } else { |
223 | if (bdl->jump_sources) { | 247 | if (bl->jump_sources) { |
224 | if (annotate_browser__opts.show_nr_jumps) { | 248 | if (annotate_browser__opts.show_nr_jumps) { |
225 | int prev; | 249 | int prev; |
226 | printed = scnprintf(bf, sizeof(bf), "%*d ", | 250 | printed = scnprintf(bf, sizeof(bf), "%*d ", |
227 | ab->jumps_width, | 251 | ab->jumps_width, |
228 | bdl->jump_sources); | 252 | bl->jump_sources); |
229 | prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, | 253 | prev = annotate_browser__set_jumps_percent_color(ab, bl->jump_sources, |
230 | current_entry); | 254 | current_entry); |
231 | ui_browser__write_nstring(browser, bf, printed); | 255 | ui_browser__write_nstring(browser, bf, printed); |
232 | ui_browser__set_color(browser, prev); | 256 | ui_browser__set_color(browser, prev); |
@@ -245,32 +269,14 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
245 | ui_browser__write_nstring(browser, bf, printed); | 269 | ui_browser__write_nstring(browser, bf, printed); |
246 | if (change_color) | 270 | if (change_color) |
247 | ui_browser__set_color(browser, color); | 271 | ui_browser__set_color(browser, color); |
248 | if (dl->ins.ops && dl->ins.ops->scnprintf) { | ||
249 | if (ins__is_jump(&dl->ins)) { | ||
250 | bool fwd = dl->ops.target.offset > dl->offset; | ||
251 | |||
252 | ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : | ||
253 | SLSMG_UARROW_CHAR); | ||
254 | SLsmg_write_char(' '); | ||
255 | } else if (ins__is_call(&dl->ins)) { | ||
256 | ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); | ||
257 | SLsmg_write_char(' '); | ||
258 | } else if (ins__is_ret(&dl->ins)) { | ||
259 | ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); | ||
260 | SLsmg_write_char(' '); | ||
261 | } else { | ||
262 | ui_browser__write_nstring(browser, " ", 2); | ||
263 | } | ||
264 | } else { | ||
265 | ui_browser__write_nstring(browser, " ", 2); | ||
266 | } | ||
267 | 272 | ||
268 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); | 273 | disasm_line__write(disasm_line(al), browser, bf, sizeof(bf)); |
274 | |||
269 | ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); | 275 | ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); |
270 | } | 276 | } |
271 | 277 | ||
272 | if (current_entry) | 278 | if (current_entry) |
273 | ab->selection = dl; | 279 | ab->selection = al; |
274 | } | 280 | } |
275 | 281 | ||
276 | static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) | 282 | static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) |
@@ -286,7 +292,7 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy | |||
286 | 292 | ||
287 | static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) | 293 | static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) |
288 | { | 294 | { |
289 | struct disasm_line *pos = list_prev_entry(cursor, node); | 295 | struct disasm_line *pos = list_prev_entry(cursor, al.node); |
290 | const char *name; | 296 | const char *name; |
291 | 297 | ||
292 | if (!pos) | 298 | if (!pos) |
@@ -306,8 +312,9 @@ static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) | |||
306 | static void annotate_browser__draw_current_jump(struct ui_browser *browser) | 312 | static void annotate_browser__draw_current_jump(struct ui_browser *browser) |
307 | { | 313 | { |
308 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | 314 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); |
309 | struct disasm_line *cursor = ab->selection, *target; | 315 | struct disasm_line *cursor = disasm_line(ab->selection); |
310 | struct browser_disasm_line *btarget, *bcursor; | 316 | struct annotation_line *target; |
317 | struct browser_line *btarget, *bcursor; | ||
311 | unsigned int from, to; | 318 | unsigned int from, to; |
312 | struct map_symbol *ms = ab->b.priv; | 319 | struct map_symbol *ms = ab->b.priv; |
313 | struct symbol *sym = ms->sym; | 320 | struct symbol *sym = ms->sym; |
@@ -321,11 +328,9 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
321 | return; | 328 | return; |
322 | 329 | ||
323 | target = ab->offsets[cursor->ops.target.offset]; | 330 | target = ab->offsets[cursor->ops.target.offset]; |
324 | if (!target) | ||
325 | return; | ||
326 | 331 | ||
327 | bcursor = disasm_line__browser(cursor); | 332 | bcursor = browser_line(&cursor->al); |
328 | btarget = disasm_line__browser(target); | 333 | btarget = browser_line(target); |
329 | 334 | ||
330 | if (annotate_browser__opts.hide_src_code) { | 335 | if (annotate_browser__opts.hide_src_code) { |
331 | from = bcursor->idx_asm; | 336 | from = bcursor->idx_asm; |
@@ -361,12 +366,11 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser) | |||
361 | return ret; | 366 | return ret; |
362 | } | 367 | } |
363 | 368 | ||
364 | static int disasm__cmp(struct browser_disasm_line *a, | 369 | static int disasm__cmp(struct annotation_line *a, struct annotation_line *b) |
365 | struct browser_disasm_line *b, int nr_pcnt) | ||
366 | { | 370 | { |
367 | int i; | 371 | int i; |
368 | 372 | ||
369 | for (i = 0; i < nr_pcnt; i++) { | 373 | for (i = 0; i < a->samples_nr; i++) { |
370 | if (a->samples[i].percent == b->samples[i].percent) | 374 | if (a->samples[i].percent == b->samples[i].percent) |
371 | continue; | 375 | continue; |
372 | return a->samples[i].percent < b->samples[i].percent; | 376 | return a->samples[i].percent < b->samples[i].percent; |
@@ -374,28 +378,27 @@ static int disasm__cmp(struct browser_disasm_line *a, | |||
374 | return 0; | 378 | return 0; |
375 | } | 379 | } |
376 | 380 | ||
377 | static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl, | 381 | static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al) |
378 | int nr_events) | ||
379 | { | 382 | { |
380 | struct rb_node **p = &root->rb_node; | 383 | struct rb_node **p = &root->rb_node; |
381 | struct rb_node *parent = NULL; | 384 | struct rb_node *parent = NULL; |
382 | struct browser_disasm_line *l; | 385 | struct annotation_line *l; |
383 | 386 | ||
384 | while (*p != NULL) { | 387 | while (*p != NULL) { |
385 | parent = *p; | 388 | parent = *p; |
386 | l = rb_entry(parent, struct browser_disasm_line, rb_node); | 389 | l = rb_entry(parent, struct annotation_line, rb_node); |
387 | 390 | ||
388 | if (disasm__cmp(bdl, l, nr_events)) | 391 | if (disasm__cmp(al, l)) |
389 | p = &(*p)->rb_left; | 392 | p = &(*p)->rb_left; |
390 | else | 393 | else |
391 | p = &(*p)->rb_right; | 394 | p = &(*p)->rb_right; |
392 | } | 395 | } |
393 | rb_link_node(&bdl->rb_node, parent, p); | 396 | rb_link_node(&al->rb_node, parent, p); |
394 | rb_insert_color(&bdl->rb_node, root); | 397 | rb_insert_color(&al->rb_node, root); |
395 | } | 398 | } |
396 | 399 | ||
397 | static void annotate_browser__set_top(struct annotate_browser *browser, | 400 | static void annotate_browser__set_top(struct annotate_browser *browser, |
398 | struct disasm_line *pos, u32 idx) | 401 | struct annotation_line *pos, u32 idx) |
399 | { | 402 | { |
400 | unsigned back; | 403 | unsigned back; |
401 | 404 | ||
@@ -404,7 +407,7 @@ static void annotate_browser__set_top(struct annotate_browser *browser, | |||
404 | browser->b.top_idx = browser->b.index = idx; | 407 | browser->b.top_idx = browser->b.index = idx; |
405 | 408 | ||
406 | while (browser->b.top_idx != 0 && back != 0) { | 409 | while (browser->b.top_idx != 0 && back != 0) { |
407 | pos = list_entry(pos->node.prev, struct disasm_line, node); | 410 | pos = list_entry(pos->node.prev, struct annotation_line, node); |
408 | 411 | ||
409 | if (disasm_line__filter(&browser->b, &pos->node)) | 412 | if (disasm_line__filter(&browser->b, &pos->node)) |
410 | continue; | 413 | continue; |
@@ -420,12 +423,13 @@ static void annotate_browser__set_top(struct annotate_browser *browser, | |||
420 | static void annotate_browser__set_rb_top(struct annotate_browser *browser, | 423 | static void annotate_browser__set_rb_top(struct annotate_browser *browser, |
421 | struct rb_node *nd) | 424 | struct rb_node *nd) |
422 | { | 425 | { |
423 | struct browser_disasm_line *bpos; | 426 | struct browser_line *bpos; |
424 | struct disasm_line *pos; | 427 | struct annotation_line *pos; |
425 | u32 idx; | 428 | u32 idx; |
426 | 429 | ||
427 | bpos = rb_entry(nd, struct browser_disasm_line, rb_node); | 430 | pos = rb_entry(nd, struct annotation_line, rb_node); |
428 | pos = ((struct disasm_line *)bpos) - 1; | 431 | bpos = browser_line(pos); |
432 | |||
429 | idx = bpos->idx; | 433 | idx = bpos->idx; |
430 | if (annotate_browser__opts.hide_src_code) | 434 | if (annotate_browser__opts.hide_src_code) |
431 | idx = bpos->idx_asm; | 435 | idx = bpos->idx_asm; |
@@ -439,46 +443,35 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
439 | struct map_symbol *ms = browser->b.priv; | 443 | struct map_symbol *ms = browser->b.priv; |
440 | struct symbol *sym = ms->sym; | 444 | struct symbol *sym = ms->sym; |
441 | struct annotation *notes = symbol__annotation(sym); | 445 | struct annotation *notes = symbol__annotation(sym); |
442 | struct disasm_line *pos, *next; | 446 | struct disasm_line *pos; |
443 | s64 len = symbol__size(sym); | ||
444 | 447 | ||
445 | browser->entries = RB_ROOT; | 448 | browser->entries = RB_ROOT; |
446 | 449 | ||
447 | pthread_mutex_lock(¬es->lock); | 450 | pthread_mutex_lock(¬es->lock); |
448 | 451 | ||
449 | list_for_each_entry(pos, ¬es->src->source, node) { | 452 | symbol__calc_percent(sym, evsel); |
450 | struct browser_disasm_line *bpos = disasm_line__browser(pos); | 453 | |
451 | const char *path = NULL; | 454 | list_for_each_entry(pos, ¬es->src->source, al.node) { |
452 | double max_percent = 0.0; | 455 | double max_percent = 0.0; |
453 | int i; | 456 | int i; |
454 | 457 | ||
455 | if (pos->offset == -1) { | 458 | if (pos->al.offset == -1) { |
456 | RB_CLEAR_NODE(&bpos->rb_node); | 459 | RB_CLEAR_NODE(&pos->al.rb_node); |
457 | continue; | 460 | continue; |
458 | } | 461 | } |
459 | 462 | ||
460 | next = disasm__get_next_ip_line(¬es->src->source, pos); | 463 | for (i = 0; i < pos->al.samples_nr; i++) { |
461 | 464 | struct annotation_data *sample = &pos->al.samples[i]; | |
462 | for (i = 0; i < browser->nr_events; i++) { | ||
463 | struct sym_hist_entry sample; | ||
464 | |||
465 | bpos->samples[i].percent = disasm__calc_percent(notes, | ||
466 | evsel->idx + i, | ||
467 | pos->offset, | ||
468 | next ? next->offset : len, | ||
469 | &path, &sample); | ||
470 | bpos->samples[i].he = sample; | ||
471 | 465 | ||
472 | if (max_percent < bpos->samples[i].percent) | 466 | if (max_percent < sample->percent) |
473 | max_percent = bpos->samples[i].percent; | 467 | max_percent = sample->percent; |
474 | } | 468 | } |
475 | 469 | ||
476 | if (max_percent < 0.01 && pos->ipc == 0) { | 470 | if (max_percent < 0.01 && pos->al.ipc == 0) { |
477 | RB_CLEAR_NODE(&bpos->rb_node); | 471 | RB_CLEAR_NODE(&pos->al.rb_node); |
478 | continue; | 472 | continue; |
479 | } | 473 | } |
480 | disasm_rb_tree__insert(&browser->entries, bpos, | 474 | disasm_rb_tree__insert(&browser->entries, &pos->al); |
481 | browser->nr_events); | ||
482 | } | 475 | } |
483 | pthread_mutex_unlock(¬es->lock); | 476 | pthread_mutex_unlock(¬es->lock); |
484 | 477 | ||
@@ -487,38 +480,38 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
487 | 480 | ||
488 | static bool annotate_browser__toggle_source(struct annotate_browser *browser) | 481 | static bool annotate_browser__toggle_source(struct annotate_browser *browser) |
489 | { | 482 | { |
490 | struct disasm_line *dl; | 483 | struct annotation_line *al; |
491 | struct browser_disasm_line *bdl; | 484 | struct browser_line *bl; |
492 | off_t offset = browser->b.index - browser->b.top_idx; | 485 | off_t offset = browser->b.index - browser->b.top_idx; |
493 | 486 | ||
494 | browser->b.seek(&browser->b, offset, SEEK_CUR); | 487 | browser->b.seek(&browser->b, offset, SEEK_CUR); |
495 | dl = list_entry(browser->b.top, struct disasm_line, node); | 488 | al = list_entry(browser->b.top, struct annotation_line, node); |
496 | bdl = disasm_line__browser(dl); | 489 | bl = browser_line(al); |
497 | 490 | ||
498 | if (annotate_browser__opts.hide_src_code) { | 491 | if (annotate_browser__opts.hide_src_code) { |
499 | if (bdl->idx_asm < offset) | 492 | if (bl->idx_asm < offset) |
500 | offset = bdl->idx; | 493 | offset = bl->idx; |
501 | 494 | ||
502 | browser->b.nr_entries = browser->nr_entries; | 495 | browser->b.nr_entries = browser->nr_entries; |
503 | annotate_browser__opts.hide_src_code = false; | 496 | annotate_browser__opts.hide_src_code = false; |
504 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | 497 | browser->b.seek(&browser->b, -offset, SEEK_CUR); |
505 | browser->b.top_idx = bdl->idx - offset; | 498 | browser->b.top_idx = bl->idx - offset; |
506 | browser->b.index = bdl->idx; | 499 | browser->b.index = bl->idx; |
507 | } else { | 500 | } else { |
508 | if (bdl->idx_asm < 0) { | 501 | if (bl->idx_asm < 0) { |
509 | ui_helpline__puts("Only available for assembly lines."); | 502 | ui_helpline__puts("Only available for assembly lines."); |
510 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | 503 | browser->b.seek(&browser->b, -offset, SEEK_CUR); |
511 | return false; | 504 | return false; |
512 | } | 505 | } |
513 | 506 | ||
514 | if (bdl->idx_asm < offset) | 507 | if (bl->idx_asm < offset) |
515 | offset = bdl->idx_asm; | 508 | offset = bl->idx_asm; |
516 | 509 | ||
517 | browser->b.nr_entries = browser->nr_asm_entries; | 510 | browser->b.nr_entries = browser->nr_asm_entries; |
518 | annotate_browser__opts.hide_src_code = true; | 511 | annotate_browser__opts.hide_src_code = true; |
519 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | 512 | browser->b.seek(&browser->b, -offset, SEEK_CUR); |
520 | browser->b.top_idx = bdl->idx_asm - offset; | 513 | browser->b.top_idx = bl->idx_asm - offset; |
521 | browser->b.index = bdl->idx_asm; | 514 | browser->b.index = bl->idx_asm; |
522 | } | 515 | } |
523 | 516 | ||
524 | return true; | 517 | return true; |
@@ -543,7 +536,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, | |||
543 | struct hist_browser_timer *hbt) | 536 | struct hist_browser_timer *hbt) |
544 | { | 537 | { |
545 | struct map_symbol *ms = browser->b.priv; | 538 | struct map_symbol *ms = browser->b.priv; |
546 | struct disasm_line *dl = browser->selection; | 539 | struct disasm_line *dl = disasm_line(browser->selection); |
547 | struct annotation *notes; | 540 | struct annotation *notes; |
548 | struct addr_map_symbol target = { | 541 | struct addr_map_symbol target = { |
549 | .map = ms->map, | 542 | .map = ms->map, |
@@ -589,10 +582,10 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows | |||
589 | struct disasm_line *pos; | 582 | struct disasm_line *pos; |
590 | 583 | ||
591 | *idx = 0; | 584 | *idx = 0; |
592 | list_for_each_entry(pos, ¬es->src->source, node) { | 585 | list_for_each_entry(pos, ¬es->src->source, al.node) { |
593 | if (pos->offset == offset) | 586 | if (pos->al.offset == offset) |
594 | return pos; | 587 | return pos; |
595 | if (!disasm_line__filter(&browser->b, &pos->node)) | 588 | if (!disasm_line__filter(&browser->b, &pos->al.node)) |
596 | ++*idx; | 589 | ++*idx; |
597 | } | 590 | } |
598 | 591 | ||
@@ -601,7 +594,7 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows | |||
601 | 594 | ||
602 | static bool annotate_browser__jump(struct annotate_browser *browser) | 595 | static bool annotate_browser__jump(struct annotate_browser *browser) |
603 | { | 596 | { |
604 | struct disasm_line *dl = browser->selection; | 597 | struct disasm_line *dl = disasm_line(browser->selection); |
605 | u64 offset; | 598 | u64 offset; |
606 | s64 idx; | 599 | s64 idx; |
607 | 600 | ||
@@ -615,29 +608,29 @@ static bool annotate_browser__jump(struct annotate_browser *browser) | |||
615 | return true; | 608 | return true; |
616 | } | 609 | } |
617 | 610 | ||
618 | annotate_browser__set_top(browser, dl, idx); | 611 | annotate_browser__set_top(browser, &dl->al, idx); |
619 | 612 | ||
620 | return true; | 613 | return true; |
621 | } | 614 | } |
622 | 615 | ||
623 | static | 616 | static |
624 | struct disasm_line *annotate_browser__find_string(struct annotate_browser *browser, | 617 | struct annotation_line *annotate_browser__find_string(struct annotate_browser *browser, |
625 | char *s, s64 *idx) | 618 | char *s, s64 *idx) |
626 | { | 619 | { |
627 | struct map_symbol *ms = browser->b.priv; | 620 | struct map_symbol *ms = browser->b.priv; |
628 | struct symbol *sym = ms->sym; | 621 | struct symbol *sym = ms->sym; |
629 | struct annotation *notes = symbol__annotation(sym); | 622 | struct annotation *notes = symbol__annotation(sym); |
630 | struct disasm_line *pos = browser->selection; | 623 | struct annotation_line *al = browser->selection; |
631 | 624 | ||
632 | *idx = browser->b.index; | 625 | *idx = browser->b.index; |
633 | list_for_each_entry_continue(pos, ¬es->src->source, node) { | 626 | list_for_each_entry_continue(al, ¬es->src->source, node) { |
634 | if (disasm_line__filter(&browser->b, &pos->node)) | 627 | if (disasm_line__filter(&browser->b, &al->node)) |
635 | continue; | 628 | continue; |
636 | 629 | ||
637 | ++*idx; | 630 | ++*idx; |
638 | 631 | ||
639 | if (pos->line && strstr(pos->line, s) != NULL) | 632 | if (al->line && strstr(al->line, s) != NULL) |
640 | return pos; | 633 | return al; |
641 | } | 634 | } |
642 | 635 | ||
643 | return NULL; | 636 | return NULL; |
@@ -645,38 +638,38 @@ struct disasm_line *annotate_browser__find_string(struct annotate_browser *brows | |||
645 | 638 | ||
646 | static bool __annotate_browser__search(struct annotate_browser *browser) | 639 | static bool __annotate_browser__search(struct annotate_browser *browser) |
647 | { | 640 | { |
648 | struct disasm_line *dl; | 641 | struct annotation_line *al; |
649 | s64 idx; | 642 | s64 idx; |
650 | 643 | ||
651 | dl = annotate_browser__find_string(browser, browser->search_bf, &idx); | 644 | al = annotate_browser__find_string(browser, browser->search_bf, &idx); |
652 | if (dl == NULL) { | 645 | if (al == NULL) { |
653 | ui_helpline__puts("String not found!"); | 646 | ui_helpline__puts("String not found!"); |
654 | return false; | 647 | return false; |
655 | } | 648 | } |
656 | 649 | ||
657 | annotate_browser__set_top(browser, dl, idx); | 650 | annotate_browser__set_top(browser, al, idx); |
658 | browser->searching_backwards = false; | 651 | browser->searching_backwards = false; |
659 | return true; | 652 | return true; |
660 | } | 653 | } |
661 | 654 | ||
662 | static | 655 | static |
663 | struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, | 656 | struct annotation_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, |
664 | char *s, s64 *idx) | 657 | char *s, s64 *idx) |
665 | { | 658 | { |
666 | struct map_symbol *ms = browser->b.priv; | 659 | struct map_symbol *ms = browser->b.priv; |
667 | struct symbol *sym = ms->sym; | 660 | struct symbol *sym = ms->sym; |
668 | struct annotation *notes = symbol__annotation(sym); | 661 | struct annotation *notes = symbol__annotation(sym); |
669 | struct disasm_line *pos = browser->selection; | 662 | struct annotation_line *al = browser->selection; |
670 | 663 | ||
671 | *idx = browser->b.index; | 664 | *idx = browser->b.index; |
672 | list_for_each_entry_continue_reverse(pos, ¬es->src->source, node) { | 665 | list_for_each_entry_continue_reverse(al, ¬es->src->source, node) { |
673 | if (disasm_line__filter(&browser->b, &pos->node)) | 666 | if (disasm_line__filter(&browser->b, &al->node)) |
674 | continue; | 667 | continue; |
675 | 668 | ||
676 | --*idx; | 669 | --*idx; |
677 | 670 | ||
678 | if (pos->line && strstr(pos->line, s) != NULL) | 671 | if (al->line && strstr(al->line, s) != NULL) |
679 | return pos; | 672 | return al; |
680 | } | 673 | } |
681 | 674 | ||
682 | return NULL; | 675 | return NULL; |
@@ -684,16 +677,16 @@ struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browse | |||
684 | 677 | ||
685 | static bool __annotate_browser__search_reverse(struct annotate_browser *browser) | 678 | static bool __annotate_browser__search_reverse(struct annotate_browser *browser) |
686 | { | 679 | { |
687 | struct disasm_line *dl; | 680 | struct annotation_line *al; |
688 | s64 idx; | 681 | s64 idx; |
689 | 682 | ||
690 | dl = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); | 683 | al = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); |
691 | if (dl == NULL) { | 684 | if (al == NULL) { |
692 | ui_helpline__puts("String not found!"); | 685 | ui_helpline__puts("String not found!"); |
693 | return false; | 686 | return false; |
694 | } | 687 | } |
695 | 688 | ||
696 | annotate_browser__set_top(browser, dl, idx); | 689 | annotate_browser__set_top(browser, al, idx); |
697 | browser->searching_backwards = true; | 690 | browser->searching_backwards = true; |
698 | return true; | 691 | return true; |
699 | } | 692 | } |
@@ -899,13 +892,16 @@ show_help: | |||
899 | continue; | 892 | continue; |
900 | case K_ENTER: | 893 | case K_ENTER: |
901 | case K_RIGHT: | 894 | case K_RIGHT: |
895 | { | ||
896 | struct disasm_line *dl = disasm_line(browser->selection); | ||
897 | |||
902 | if (browser->selection == NULL) | 898 | if (browser->selection == NULL) |
903 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); | 899 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); |
904 | else if (browser->selection->offset == -1) | 900 | else if (browser->selection->offset == -1) |
905 | ui_helpline__puts("Actions are only available for assembly lines."); | 901 | ui_helpline__puts("Actions are only available for assembly lines."); |
906 | else if (!browser->selection->ins.ops) | 902 | else if (!dl->ins.ops) |
907 | goto show_sup_ins; | 903 | goto show_sup_ins; |
908 | else if (ins__is_ret(&browser->selection->ins)) | 904 | else if (ins__is_ret(&dl->ins)) |
909 | goto out; | 905 | goto out; |
910 | else if (!(annotate_browser__jump(browser) || | 906 | else if (!(annotate_browser__jump(browser) || |
911 | annotate_browser__callq(browser, evsel, hbt))) { | 907 | annotate_browser__callq(browser, evsel, hbt))) { |
@@ -913,6 +909,7 @@ show_sup_ins: | |||
913 | ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions."); | 909 | ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions."); |
914 | } | 910 | } |
915 | continue; | 911 | continue; |
912 | } | ||
916 | case 't': | 913 | case 't': |
917 | if (annotate_browser__opts.show_total_period) { | 914 | if (annotate_browser__opts.show_total_period) { |
918 | annotate_browser__opts.show_total_period = false; | 915 | annotate_browser__opts.show_total_period = false; |
@@ -990,10 +987,10 @@ static void count_and_fill(struct annotate_browser *browser, u64 start, u64 end, | |||
990 | return; | 987 | return; |
991 | 988 | ||
992 | for (offset = start; offset <= end; offset++) { | 989 | for (offset = start; offset <= end; offset++) { |
993 | struct disasm_line *dl = browser->offsets[offset]; | 990 | struct annotation_line *al = browser->offsets[offset]; |
994 | 991 | ||
995 | if (dl) | 992 | if (al) |
996 | dl->ipc = ipc; | 993 | al->ipc = ipc; |
997 | } | 994 | } |
998 | } | 995 | } |
999 | } | 996 | } |
@@ -1018,13 +1015,13 @@ static void annotate__compute_ipc(struct annotate_browser *browser, size_t size, | |||
1018 | 1015 | ||
1019 | ch = ¬es->src->cycles_hist[offset]; | 1016 | ch = ¬es->src->cycles_hist[offset]; |
1020 | if (ch && ch->cycles) { | 1017 | if (ch && ch->cycles) { |
1021 | struct disasm_line *dl; | 1018 | struct annotation_line *al; |
1022 | 1019 | ||
1023 | if (ch->have_start) | 1020 | if (ch->have_start) |
1024 | count_and_fill(browser, ch->start, offset, ch); | 1021 | count_and_fill(browser, ch->start, offset, ch); |
1025 | dl = browser->offsets[offset]; | 1022 | al = browser->offsets[offset]; |
1026 | if (dl && ch->num_aggr) | 1023 | if (al && ch->num_aggr) |
1027 | dl->cycles = ch->cycles_aggr / ch->num_aggr; | 1024 | al->cycles = ch->cycles_aggr / ch->num_aggr; |
1028 | browser->have_cycles = true; | 1025 | browser->have_cycles = true; |
1029 | } | 1026 | } |
1030 | } | 1027 | } |
@@ -1043,23 +1040,27 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser | |||
1043 | return; | 1040 | return; |
1044 | 1041 | ||
1045 | for (offset = 0; offset < size; ++offset) { | 1042 | for (offset = 0; offset < size; ++offset) { |
1046 | struct disasm_line *dl = browser->offsets[offset], *dlt; | 1043 | struct annotation_line *al = browser->offsets[offset]; |
1047 | struct browser_disasm_line *bdlt; | 1044 | struct disasm_line *dl; |
1045 | struct browser_line *blt; | ||
1046 | |||
1047 | dl = disasm_line(al); | ||
1048 | 1048 | ||
1049 | if (!disasm_line__is_valid_jump(dl, sym)) | 1049 | if (!disasm_line__is_valid_jump(dl, sym)) |
1050 | continue; | 1050 | continue; |
1051 | 1051 | ||
1052 | dlt = browser->offsets[dl->ops.target.offset]; | 1052 | al = browser->offsets[dl->ops.target.offset]; |
1053 | |||
1053 | /* | 1054 | /* |
1054 | * FIXME: Oops, no jump target? Buggy disassembler? Or do we | 1055 | * FIXME: Oops, no jump target? Buggy disassembler? Or do we |
1055 | * have to adjust to the previous offset? | 1056 | * have to adjust to the previous offset? |
1056 | */ | 1057 | */ |
1057 | if (dlt == NULL) | 1058 | if (al == NULL) |
1058 | continue; | 1059 | continue; |
1059 | 1060 | ||
1060 | bdlt = disasm_line__browser(dlt); | 1061 | blt = browser_line(al); |
1061 | if (++bdlt->jump_sources > browser->max_jump_sources) | 1062 | if (++blt->jump_sources > browser->max_jump_sources) |
1062 | browser->max_jump_sources = bdlt->jump_sources; | 1063 | browser->max_jump_sources = blt->jump_sources; |
1063 | 1064 | ||
1064 | ++browser->nr_jumps; | 1065 | ++browser->nr_jumps; |
1065 | } | 1066 | } |
@@ -1078,7 +1079,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1078 | struct perf_evsel *evsel, | 1079 | struct perf_evsel *evsel, |
1079 | struct hist_browser_timer *hbt) | 1080 | struct hist_browser_timer *hbt) |
1080 | { | 1081 | { |
1081 | struct disasm_line *pos, *n; | 1082 | struct annotation_line *al; |
1082 | struct annotation *notes; | 1083 | struct annotation *notes; |
1083 | size_t size; | 1084 | size_t size; |
1084 | struct map_symbol ms = { | 1085 | struct map_symbol ms = { |
@@ -1097,7 +1098,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1097 | }; | 1098 | }; |
1098 | int ret = -1, err; | 1099 | int ret = -1, err; |
1099 | int nr_pcnt = 1; | 1100 | int nr_pcnt = 1; |
1100 | size_t sizeof_bdl = sizeof(struct browser_disasm_line); | ||
1101 | 1101 | ||
1102 | if (sym == NULL) | 1102 | if (sym == NULL) |
1103 | return -1; | 1103 | return -1; |
@@ -1107,21 +1107,16 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1107 | if (map->dso->annotate_warned) | 1107 | if (map->dso->annotate_warned) |
1108 | return -1; | 1108 | return -1; |
1109 | 1109 | ||
1110 | browser.offsets = zalloc(size * sizeof(struct disasm_line *)); | 1110 | browser.offsets = zalloc(size * sizeof(struct annotation_line *)); |
1111 | if (browser.offsets == NULL) { | 1111 | if (browser.offsets == NULL) { |
1112 | ui__error("Not enough memory!"); | 1112 | ui__error("Not enough memory!"); |
1113 | return -1; | 1113 | return -1; |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | if (perf_evsel__is_group_event(evsel)) { | 1116 | if (perf_evsel__is_group_event(evsel)) |
1117 | nr_pcnt = evsel->nr_members; | 1117 | nr_pcnt = evsel->nr_members; |
1118 | sizeof_bdl += sizeof(struct disasm_line_samples) * | ||
1119 | (nr_pcnt - 1); | ||
1120 | } | ||
1121 | 1118 | ||
1122 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), | 1119 | err = symbol__annotate(sym, map, evsel, sizeof(struct browser_line), &browser.arch); |
1123 | sizeof_bdl, &browser.arch, | ||
1124 | perf_evsel__env_cpuid(evsel)); | ||
1125 | if (err) { | 1120 | if (err) { |
1126 | char msg[BUFSIZ]; | 1121 | char msg[BUFSIZ]; |
1127 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); | 1122 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); |
@@ -1129,20 +1124,22 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1129 | goto out_free_offsets; | 1124 | goto out_free_offsets; |
1130 | } | 1125 | } |
1131 | 1126 | ||
1127 | symbol__calc_percent(sym, evsel); | ||
1128 | |||
1132 | ui_helpline__push("Press ESC to exit"); | 1129 | ui_helpline__push("Press ESC to exit"); |
1133 | 1130 | ||
1134 | notes = symbol__annotation(sym); | 1131 | notes = symbol__annotation(sym); |
1135 | browser.start = map__rip_2objdump(map, sym->start); | 1132 | browser.start = map__rip_2objdump(map, sym->start); |
1136 | 1133 | ||
1137 | list_for_each_entry(pos, ¬es->src->source, node) { | 1134 | list_for_each_entry(al, ¬es->src->source, node) { |
1138 | struct browser_disasm_line *bpos; | 1135 | struct browser_line *bpos; |
1139 | size_t line_len = strlen(pos->line); | 1136 | size_t line_len = strlen(al->line); |
1140 | 1137 | ||
1141 | if (browser.b.width < line_len) | 1138 | if (browser.b.width < line_len) |
1142 | browser.b.width = line_len; | 1139 | browser.b.width = line_len; |
1143 | bpos = disasm_line__browser(pos); | 1140 | bpos = browser_line(al); |
1144 | bpos->idx = browser.nr_entries++; | 1141 | bpos->idx = browser.nr_entries++; |
1145 | if (pos->offset != -1) { | 1142 | if (al->offset != -1) { |
1146 | bpos->idx_asm = browser.nr_asm_entries++; | 1143 | bpos->idx_asm = browser.nr_asm_entries++; |
1147 | /* | 1144 | /* |
1148 | * FIXME: short term bandaid to cope with assembly | 1145 | * FIXME: short term bandaid to cope with assembly |
@@ -1151,8 +1148,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1151 | * | 1148 | * |
1152 | * E.g. copy_user_generic_unrolled | 1149 | * E.g. copy_user_generic_unrolled |
1153 | */ | 1150 | */ |
1154 | if (pos->offset < (s64)size) | 1151 | if (al->offset < (s64)size) |
1155 | browser.offsets[pos->offset] = pos; | 1152 | browser.offsets[al->offset] = al; |
1156 | } else | 1153 | } else |
1157 | bpos->idx_asm = -1; | 1154 | bpos->idx_asm = -1; |
1158 | } | 1155 | } |
@@ -1174,10 +1171,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1174 | annotate_browser__update_addr_width(&browser); | 1171 | annotate_browser__update_addr_width(&browser); |
1175 | 1172 | ||
1176 | ret = annotate_browser__run(&browser, evsel, hbt); | 1173 | ret = annotate_browser__run(&browser, evsel, hbt); |
1177 | list_for_each_entry_safe(pos, n, ¬es->src->source, node) { | 1174 | |
1178 | list_del(&pos->node); | 1175 | annotated_source__purge(notes->src); |
1179 | disasm_line__free(pos); | ||
1180 | } | ||
1181 | 1176 | ||
1182 | out_free_offsets: | 1177 | out_free_offsets: |
1183 | free(browser.offsets); | 1178 | free(browser.offsets); |