55
55
slsmg_write_nstring(" ", width - 18);
57
57
slsmg_write_nstring(ol->line, width - 18);
60
ui_browser__set_color(self, HE_COLORSET_CODE);
60
63
static double objdump_line__calc_percent(struct objdump_line *self,
61
struct list_head *head,
64
struct symbol *sym, int evidx)
64
66
double percent = 0.0;
66
68
if (self->offset != -1) {
67
69
int len = sym->end - sym->start;
68
70
unsigned int hits = 0;
69
struct sym_priv *priv = symbol__priv(sym);
70
struct sym_ext *sym_ext = priv->ext;
71
struct sym_hist *h = priv->hist;
71
struct annotation *notes = symbol__annotation(sym);
72
struct source_line *src_line = notes->src->lines;
73
struct sym_hist *h = annotation__histogram(notes, evidx);
72
74
s64 offset = self->offset;
73
struct objdump_line *next = objdump__get_next_ip_line(head, self);
75
struct objdump_line *next;
77
next = objdump__get_next_ip_line(¬es->src->source, self);
76
78
while (offset < (s64)len &&
77
79
(next == NULL || offset < next->offset)) {
79
percent += sym_ext[offset].percent;
81
percent += src_line[offset].percent;
81
hits += h->ip[offset];
83
hits += h->addr[offset];
86
if (sym_ext == NULL && h->sum)
88
* If the percentage wasn't already calculated in
89
* symbol__get_source_line, do it now:
91
if (src_line == NULL && h->sum)
87
92
percent = 100.0 * hits / h->sum;
133
138
self->curr_hot = nd;
136
static int annotate_browser__run(struct annotate_browser *self)
139
struct hist_entry *he = self->b.priv;
141
static void annotate_browser__calc_percent(struct annotate_browser *browser,
144
struct symbol *sym = browser->b.priv;
145
struct annotation *notes = symbol__annotation(sym);
146
struct objdump_line *pos;
148
browser->entries = RB_ROOT;
150
pthread_mutex_lock(¬es->lock);
152
list_for_each_entry(pos, ¬es->src->source, node) {
153
struct objdump_line_rb_node *rbpos = objdump_line__rb(pos);
154
rbpos->percent = objdump_line__calc_percent(pos, sym, evidx);
155
if (rbpos->percent < 0.01) {
156
RB_CLEAR_NODE(&rbpos->rb_node);
159
objdump__insert_line(&browser->entries, rbpos);
161
pthread_mutex_unlock(¬es->lock);
163
browser->curr_hot = rb_last(&browser->entries);
166
static int annotate_browser__run(struct annotate_browser *self, int evidx,
169
struct rb_node *nd = NULL;
170
struct symbol *sym = self->b.priv;
172
* RIGHT To allow builtin-annotate to cycle thru multiple symbols by
173
* examining the exit key for this function.
175
int exit_keys[] = { 'H', NEWT_KEY_TAB, NEWT_KEY_UNTAB,
142
if (ui_browser__show(&self->b, he->ms.sym->name,
143
"<-, -> or ESC: exit, TAB/shift+TAB: cycle thru samples") < 0)
179
if (ui_browser__show(&self->b, sym->name,
180
"<-, -> or ESC: exit, TAB/shift+TAB: "
181
"cycle hottest lines, H: Hottest") < 0)
146
* To allow builtin-annotate to cycle thru multiple symbols by
147
* examining the exit key for this function.
149
ui_browser__add_exit_key(&self->b, NEWT_KEY_RIGHT);
184
ui_browser__add_exit_keys(&self->b, exit_keys);
185
annotate_browser__calc_percent(self, evidx);
188
annotate_browser__set_top(self, self->curr_hot);
151
190
nd = self->curr_hot;
153
int tabs[] = { NEWT_KEY_TAB, NEWT_KEY_UNTAB, 0 };
154
ui_browser__add_exit_keys(&self->b, tabs);
193
newtFormSetTimer(self->b.form, refresh);
158
196
key = ui_browser__run(&self->b);
199
annotate_browser__calc_percent(self, evidx);
201
* Current line focus got out of the list of most active
202
* lines, NULL it so that if TAB|UNTAB is pressed, we
203
* move to curr_hot (current hottest line).
205
if (nd != NULL && RB_EMPTY_NODE(nd))
212
* FIXME we need to check if it was
213
* es.reason == NEWT_EXIT_TIMER
216
symbol__annotate_decay_histogram(sym, evidx);
161
218
case NEWT_KEY_TAB:
164
nd = rb_last(&self->entries);
165
annotate_browser__set_top(self, nd);
222
nd = rb_last(&self->entries);
167
226
case NEWT_KEY_UNTAB:
170
nd = rb_first(&self->entries);
171
annotate_browser__set_top(self, nd);
230
nd = rb_first(&self->entries);
242
annotate_browser__set_top(self, nd);
178
245
ui_browser__hide(&self->b);
182
int hist_entry__tui_annotate(struct hist_entry *self)
249
int hist_entry__tui_annotate(struct hist_entry *he, int evidx)
251
return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, 0);
254
int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
184
257
struct objdump_line *pos, *n;
185
struct objdump_line_rb_node *rbpos;
258
struct annotation *notes;
187
259
struct annotate_browser browser = {
190
261
.refresh = ui_browser__list_head_refresh,
191
262
.seek = ui_browser__list_head_seek,
192
263
.write = annotate_browser__write,
198
if (self->ms.sym == NULL)
201
if (self->ms.map->dso->annotate_warned)
204
if (hist_entry__annotate(self, &head, sizeof(*rbpos)) < 0) {
272
if (map->dso->annotate_warned)
275
if (symbol__annotate(sym, map, sizeof(struct objdump_line_rb_node)) < 0) {
205
276
ui__error_window(ui_helpline__last_msg);
209
280
ui_helpline__push("Press <- or ESC to exit");
211
list_for_each_entry(pos, &head, node) {
282
notes = symbol__annotation(sym);
284
list_for_each_entry(pos, ¬es->src->source, node) {
285
struct objdump_line_rb_node *rbpos;
212
286
size_t line_len = strlen(pos->line);
213
288
if (browser.b.width < line_len)
214
289
browser.b.width = line_len;
215
290
rbpos = objdump_line__rb(pos);
216
291
rbpos->idx = browser.b.nr_entries++;
217
rbpos->percent = objdump_line__calc_percent(pos, &head, self->ms.sym);
218
if (rbpos->percent < 0.01)
220
objdump__insert_line(&browser.entries, rbpos);
224
* Position the browser at the hottest line.
226
browser.curr_hot = rb_last(&browser.entries);
227
if (browser.curr_hot)
228
annotate_browser__set_top(&browser, browser.curr_hot);
294
browser.b.entries = ¬es->src->source,
230
295
browser.b.width += 18; /* Percentage */
231
ret = annotate_browser__run(&browser);
232
list_for_each_entry_safe(pos, n, &head, node) {
296
ret = annotate_browser__run(&browser, evidx, refresh);
297
list_for_each_entry_safe(pos, n, ¬es->src->source, node) {
233
298
list_del(&pos->node);
234
299
objdump_line__free(pos);