2 #include "util/debug.h"
3 #include "util/annotate.h"
4 #include "util/evsel.h"
5 #include "ui/helpline.h"
16 static const char *const col_names
[] = {
22 static int perf_gtk__get_percent(char *buf
, size_t size
, struct symbol
*sym
,
23 struct disasm_line
*dl
, int evidx
)
25 struct sym_hist
*symhist
;
32 if (dl
->offset
== (s64
) -1)
35 symhist
= annotation__histogram(symbol__annotation(sym
), evidx
);
36 if (!symbol_conf
.event_group
&& !symhist
->addr
[dl
->offset
])
39 percent
= 100.0 * symhist
->addr
[dl
->offset
] / symhist
->sum
;
41 markup
= perf_gtk__get_percent_color(percent
);
43 ret
+= scnprintf(buf
, size
, "%s", markup
);
44 ret
+= scnprintf(buf
+ ret
, size
- ret
, "%6.2f%%", percent
);
46 ret
+= scnprintf(buf
+ ret
, size
- ret
, "</span>");
51 static int perf_gtk__get_offset(char *buf
, size_t size
, struct symbol
*sym
,
52 struct map
*map
, struct disasm_line
*dl
)
54 u64 start
= map__rip_2objdump(map
, sym
->start
);
58 if (dl
->offset
== (s64
) -1)
61 return scnprintf(buf
, size
, "%"PRIx64
, start
+ dl
->offset
);
64 static int perf_gtk__get_line(char *buf
, size_t size
, struct disasm_line
*dl
)
67 char *line
= g_markup_escape_text(dl
->line
, -1);
68 const char *markup
= "<span fgcolor='gray'>";
75 if (dl
->offset
!= (s64
) -1)
79 ret
+= scnprintf(buf
, size
, "%s", markup
);
80 ret
+= scnprintf(buf
+ ret
, size
- ret
, "%s", line
);
82 ret
+= scnprintf(buf
+ ret
, size
- ret
, "</span>");
88 static int perf_gtk__annotate_symbol(GtkWidget
*window
, struct symbol
*sym
,
89 struct map
*map
, struct perf_evsel
*evsel
,
90 struct hist_browser_timer
*hbt __maybe_unused
)
92 struct disasm_line
*pos
, *n
;
93 struct annotation
*notes
;
94 GType col_types
[MAX_ANN_COLS
];
95 GtkCellRenderer
*renderer
;
101 notes
= symbol__annotation(sym
);
103 for (i
= 0; i
< MAX_ANN_COLS
; i
++) {
104 col_types
[i
] = G_TYPE_STRING
;
106 store
= gtk_list_store_newv(MAX_ANN_COLS
, col_types
);
108 view
= gtk_tree_view_new();
109 renderer
= gtk_cell_renderer_text_new();
111 for (i
= 0; i
< MAX_ANN_COLS
; i
++) {
112 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view
),
113 -1, col_names
[i
], renderer
, "markup",
117 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), GTK_TREE_MODEL(store
));
118 g_object_unref(GTK_TREE_MODEL(store
));
120 list_for_each_entry(pos
, ¬es
->src
->source
, node
) {
124 gtk_list_store_append(store
, &iter
);
126 if (perf_evsel__is_group_event(evsel
)) {
127 for (i
= 0; i
< evsel
->nr_members
; i
++) {
128 ret
+= perf_gtk__get_percent(s
+ ret
,
132 ret
+= scnprintf(s
+ ret
, sizeof(s
) - ret
, " ");
135 ret
= perf_gtk__get_percent(s
, sizeof(s
), sym
, pos
,
140 gtk_list_store_set(store
, &iter
, ANN_COL__PERCENT
, s
, -1);
141 if (perf_gtk__get_offset(s
, sizeof(s
), sym
, map
, pos
))
142 gtk_list_store_set(store
, &iter
, ANN_COL__OFFSET
, s
, -1);
143 if (perf_gtk__get_line(s
, sizeof(s
), pos
))
144 gtk_list_store_set(store
, &iter
, ANN_COL__LINE
, s
, -1);
147 gtk_container_add(GTK_CONTAINER(window
), view
);
149 list_for_each_entry_safe(pos
, n
, ¬es
->src
->source
, node
) {
150 list_del(&pos
->node
);
151 disasm_line__free(pos
);
157 static int symbol__gtk_annotate(struct symbol
*sym
, struct map
*map
,
158 struct perf_evsel
*evsel
,
159 struct hist_browser_timer
*hbt
)
163 GtkWidget
*scrolled_window
;
164 GtkWidget
*tab_label
;
166 if (map
->dso
->annotate_warned
)
169 if (symbol__annotate(sym
, map
, 0) < 0) {
170 ui__error("%s", ui_helpline__current
);
174 if (perf_gtk__is_active_context(pgctx
)) {
175 window
= pgctx
->main_window
;
176 notebook
= pgctx
->notebook
;
182 signal(SIGSEGV
, perf_gtk__signal
);
183 signal(SIGFPE
, perf_gtk__signal
);
184 signal(SIGINT
, perf_gtk__signal
);
185 signal(SIGQUIT
, perf_gtk__signal
);
186 signal(SIGTERM
, perf_gtk__signal
);
188 window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
189 gtk_window_set_title(GTK_WINDOW(window
), "perf annotate");
191 g_signal_connect(window
, "delete_event", gtk_main_quit
, NULL
);
193 pgctx
= perf_gtk__activate_context(window
);
197 vbox
= gtk_vbox_new(FALSE
, 0);
198 notebook
= gtk_notebook_new();
199 pgctx
->notebook
= notebook
;
201 gtk_box_pack_start(GTK_BOX(vbox
), notebook
, TRUE
, TRUE
, 0);
203 infobar
= perf_gtk__setup_info_bar();
205 gtk_box_pack_start(GTK_BOX(vbox
), infobar
,
209 statbar
= perf_gtk__setup_statusbar();
210 gtk_box_pack_start(GTK_BOX(vbox
), statbar
, FALSE
, FALSE
, 0);
212 gtk_container_add(GTK_CONTAINER(window
), vbox
);
215 scrolled_window
= gtk_scrolled_window_new(NULL
, NULL
);
216 tab_label
= gtk_label_new(sym
->name
);
218 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window
),
219 GTK_POLICY_AUTOMATIC
,
220 GTK_POLICY_AUTOMATIC
);
222 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), scrolled_window
,
225 perf_gtk__annotate_symbol(scrolled_window
, sym
, map
, evsel
, hbt
);
229 int hist_entry__gtk_annotate(struct hist_entry
*he
,
230 struct perf_evsel
*evsel
,
231 struct hist_browser_timer
*hbt
)
233 return symbol__gtk_annotate(he
->ms
.sym
, he
->ms
.map
, evsel
, hbt
);
236 void perf_gtk__show_annotations(void)
240 if (!perf_gtk__is_active_context(pgctx
))
243 window
= pgctx
->main_window
;
244 gtk_widget_show_all(window
);
246 perf_gtk__resize_window(window
);
247 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
251 perf_gtk__deactivate_context(&pgctx
);