diff options
author | Richard Purdie <richard@openedhand.com> | 2007-02-22 16:58:36 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2007-02-22 16:58:36 +0000 |
commit | 1b447bc1c9f5c9b6bd39e2ce2d24e78813422b5d (patch) | |
tree | 62ea7d1896621d3085ee25dfe1d2571f4d36ae10 | |
parent | 1a8420b775f36dadd47f848df412092858f8659c (diff) | |
download | poky-1b447bc1c9f5c9b6bd39e2ce2d24e78813422b5d.tar.gz |
oprofile: Add ability to output XML callgraph information
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1289 311d38ba-8fff-0310-9ca6-ca027cbcb966
-rw-r--r-- | meta/packages/oprofile/oprofile/xml_callgraph.patch | 759 | ||||
-rw-r--r-- | meta/packages/oprofile/oprofile_cvs.bb | 3 |
2 files changed, 761 insertions, 1 deletions
diff --git a/meta/packages/oprofile/oprofile/xml_callgraph.patch b/meta/packages/oprofile/oprofile/xml_callgraph.patch new file mode 100644 index 0000000000..0c2b567614 --- /dev/null +++ b/meta/packages/oprofile/oprofile/xml_callgraph.patch | |||
@@ -0,0 +1,759 @@ | |||
1 | Index: oprofile/libpp/callgraph_container.cpp | ||
2 | =================================================================== | ||
3 | --- oprofile.orig/libpp/callgraph_container.cpp | ||
4 | +++ oprofile/libpp/callgraph_container.cpp | ||
5 | @@ -379,17 +379,19 @@ process(count_array_t total, double thre | ||
6 | |||
7 | process_children(sym, threshold); | ||
8 | |||
9 | - cg_syms.push_back(sym); | ||
10 | + cg_syms_objs.push_back(sym); | ||
11 | } | ||
12 | + | ||
13 | + for (unsigned int i = 0; i < cg_syms_objs.size(); i++) | ||
14 | + cg_syms.push_back(&cg_syms_objs[i]); | ||
15 | } | ||
16 | |||
17 | |||
18 | -cg_collection arc_recorder::get_symbols() const | ||
19 | +symbol_collection arc_recorder::get_symbols() const | ||
20 | { | ||
21 | return cg_syms; | ||
22 | } | ||
23 | |||
24 | - | ||
25 | void callgraph_container::populate(string const & archive_path, | ||
26 | list<inverted_profile> const & iprofiles, | ||
27 | extra_images const & extra, bool debug_info, double threshold, | ||
28 | @@ -580,12 +582,14 @@ column_flags callgraph_container::output | ||
29 | column_flags output_hints = cf_none; | ||
30 | |||
31 | // FIXME: costly: must we access directly recorder map ? | ||
32 | - cg_collection syms = recorder.get_symbols(); | ||
33 | + symbol_collection syms = recorder.get_symbols(); | ||
34 | |||
35 | - cg_collection::const_iterator it; | ||
36 | - cg_collection::const_iterator const end = syms.end(); | ||
37 | - for (it = syms.begin(); it != end; ++it) | ||
38 | - output_hints = it->output_hint(output_hints); | ||
39 | + symbol_collection::iterator it; | ||
40 | + symbol_collection::iterator const end = syms.end(); | ||
41 | + for (it = syms.begin(); it != end; ++it) { | ||
42 | + cg_symbol const *cg_symb = dynamic_cast<const cg_symbol *>(*it); | ||
43 | + output_hints = cg_symb->output_hint(output_hints); | ||
44 | + } | ||
45 | |||
46 | return output_hints; | ||
47 | } | ||
48 | @@ -597,7 +601,7 @@ count_array_t callgraph_container::sampl | ||
49 | } | ||
50 | |||
51 | |||
52 | -cg_collection callgraph_container::get_symbols() const | ||
53 | +symbol_collection callgraph_container::get_symbols() const | ||
54 | { | ||
55 | return recorder.get_symbols(); | ||
56 | } | ||
57 | Index: oprofile/libpp/callgraph_container.h | ||
58 | =================================================================== | ||
59 | --- oprofile.orig/libpp/callgraph_container.h | ||
60 | +++ oprofile/libpp/callgraph_container.h | ||
61 | @@ -53,7 +53,7 @@ public: | ||
62 | count_array_t const & arc_count); | ||
63 | |||
64 | /// return all the cg symbols | ||
65 | - cg_collection get_symbols() const; | ||
66 | + symbol_collection get_symbols() const; | ||
67 | |||
68 | /** | ||
69 | * After population, build the final output, and do | ||
70 | @@ -91,7 +91,8 @@ private: | ||
71 | map_t sym_map; | ||
72 | |||
73 | /// final output data | ||
74 | - cg_collection cg_syms; | ||
75 | + symbol_collection cg_syms; | ||
76 | + cg_collection_objs cg_syms_objs; | ||
77 | }; | ||
78 | |||
79 | |||
80 | @@ -126,7 +127,7 @@ public: | ||
81 | count_array_t samples_count() const; | ||
82 | |||
83 | // return all the cg symbols | ||
84 | - cg_collection get_symbols() const; | ||
85 | + symbol_collection get_symbols() const; | ||
86 | |||
87 | private: | ||
88 | /** | ||
89 | Index: oprofile/libpp/format_output.cpp | ||
90 | =================================================================== | ||
91 | --- oprofile.orig/libpp/format_output.cpp | ||
92 | +++ oprofile/libpp/format_output.cpp | ||
93 | @@ -489,7 +489,7 @@ cg_formatter::cg_formatter(callgraph_con | ||
94 | } | ||
95 | |||
96 | |||
97 | -void cg_formatter::output(ostream & out, cg_collection const & syms) | ||
98 | +void cg_formatter::output(ostream & out, symbol_collection const & syms) | ||
99 | { | ||
100 | // amount of spacing prefixing child and parent lines | ||
101 | string const child_parent_prefix(" "); | ||
102 | @@ -498,37 +498,37 @@ void cg_formatter::output(ostream & out, | ||
103 | |||
104 | out << string(79, '-') << endl; | ||
105 | |||
106 | - cg_collection::const_iterator it; | ||
107 | - cg_collection::const_iterator end = syms.end(); | ||
108 | + symbol_collection::const_iterator it; | ||
109 | + symbol_collection::const_iterator end = syms.end(); | ||
110 | |||
111 | for (it = syms.begin(); it < end; ++it) { | ||
112 | - cg_symbol const & sym = *it; | ||
113 | + cg_symbol const *sym = dynamic_cast<const cg_symbol *>(*it); | ||
114 | |||
115 | cg_symbol::children::const_iterator cit; | ||
116 | - cg_symbol::children::const_iterator cend = sym.callers.end(); | ||
117 | + cg_symbol::children::const_iterator cend = sym->callers.end(); | ||
118 | |||
119 | counts_t c; | ||
120 | if (global_percent) | ||
121 | c.total = counts.total; | ||
122 | else | ||
123 | - c.total = sym.total_caller_count; | ||
124 | + c.total = sym->total_caller_count; | ||
125 | |||
126 | - for (cit = sym.callers.begin(); cit != cend; ++cit) { | ||
127 | + for (cit = sym->callers.begin(); cit != cend; ++cit) { | ||
128 | out << child_parent_prefix; | ||
129 | do_output(out, *cit, cit->sample, c); | ||
130 | } | ||
131 | |||
132 | - do_output(out, sym, sym.sample, counts); | ||
133 | + do_output(out, *sym, sym->sample, counts); | ||
134 | |||
135 | c = counts_t(); | ||
136 | if (global_percent) | ||
137 | c.total = counts.total; | ||
138 | else | ||
139 | - c.total = sym.total_callee_count; | ||
140 | + c.total = sym->total_callee_count; | ||
141 | |||
142 | - cend = sym.callees.end(); | ||
143 | + cend = sym->callees.end(); | ||
144 | |||
145 | - for (cit = sym.callees.begin(); cit != cend; ++cit) { | ||
146 | + for (cit = sym->callees.begin(); cit != cend; ++cit) { | ||
147 | out << child_parent_prefix; | ||
148 | do_output(out, *cit, cit->sample, c); | ||
149 | } | ||
150 | @@ -562,6 +562,20 @@ ostringstream bytes_out; | ||
151 | map<string, size_t> symbol_data_table; | ||
152 | size_t symbol_data_index = 0; | ||
153 | |||
154 | +/* Return any existing index or add to the table */ | ||
155 | +size_t xml_get_symbol_index(string const name) | ||
156 | +{ | ||
157 | + size_t index = symbol_data_index; | ||
158 | + map<string, size_t>::iterator it = symbol_data_table.find(name); | ||
159 | + | ||
160 | + if (it == symbol_data_table.end()) { | ||
161 | + symbol_data_table[name] = symbol_data_index++; | ||
162 | + return index; | ||
163 | + } | ||
164 | + | ||
165 | + return it->second; | ||
166 | +} | ||
167 | + | ||
168 | |||
169 | class symbol_details_t { | ||
170 | public: | ||
171 | @@ -577,14 +591,15 @@ symbol_details_array_t symbol_details; | ||
172 | size_t detail_table_index = 0; | ||
173 | |||
174 | xml_formatter:: | ||
175 | -xml_formatter(profile_container const & p, | ||
176 | +xml_formatter(profile_container const *p, | ||
177 | symbol_collection & s) | ||
178 | : | ||
179 | profile(p), | ||
180 | symbols(s), | ||
181 | need_details(false) | ||
182 | { | ||
183 | - counts.total = profile.samples_count(); | ||
184 | + if (profile) | ||
185 | + counts.total = profile->samples_count(); | ||
186 | } | ||
187 | |||
188 | |||
189 | @@ -640,12 +655,11 @@ void xml_formatter::output_symbol_data(o | ||
190 | string const image = get_image_name(symb->image_name, true); | ||
191 | string const qname = image + ":" + name; | ||
192 | map<string, size_t>::iterator sd_it = symbol_data_table.find(qname); | ||
193 | - size_t si = xml_support->get_symbol_index(it); | ||
194 | |||
195 | - if (sd_it->second == si) { | ||
196 | + if (sd_it != symbol_data_table.end()) { | ||
197 | // first time we've seen this symbol | ||
198 | out << open_element(SYMBOL_DATA, true); | ||
199 | - out << init_attr(TABLE_ID, si); | ||
200 | + out << init_attr(TABLE_ID, sd_it->second); | ||
201 | |||
202 | field_datum datum(*symb, symb->sample, 0, counts); | ||
203 | |||
204 | @@ -660,9 +674,12 @@ void xml_formatter::output_symbol_data(o | ||
205 | output_attribute(out, datum, ff_vma, STARTING_ADDR); | ||
206 | |||
207 | if (need_details) | ||
208 | - xml_support->output_symbol_bytes(bytes_out, symb, si); | ||
209 | + xml_support->output_symbol_bytes(bytes_out, symb, sd_it->second); | ||
210 | } | ||
211 | out << close_element(); | ||
212 | + | ||
213 | + // seen so remove (otherwise get several "no symbols") | ||
214 | + symbol_data_table.erase(qname); | ||
215 | } | ||
216 | } | ||
217 | out << close_element(SYMBOL_TABLE); | ||
218 | @@ -675,8 +692,8 @@ output_symbol_details(symbol_entry const | ||
219 | if (!has_sample_counts(symb->sample.counts, lo, hi)) | ||
220 | return ""; | ||
221 | |||
222 | - sample_container::samples_iterator it = profile.begin(symb); | ||
223 | - sample_container::samples_iterator end = profile.end(symb); | ||
224 | + sample_container::samples_iterator it = profile->begin(symb); | ||
225 | + sample_container::samples_iterator end = profile->end(symb); | ||
226 | |||
227 | ostringstream str; | ||
228 | for (; it != end; ++it) { | ||
229 | @@ -725,10 +742,10 @@ output_symbol_details(symbol_entry const | ||
230 | |||
231 | void xml_formatter:: | ||
232 | output_symbol(ostream & out, | ||
233 | - symbol_collection::const_iterator const it, size_t lo, size_t hi) | ||
234 | + symbol_entry const * symb, size_t lo, size_t hi) | ||
235 | { | ||
236 | - symbol_entry const * symb = *it; | ||
237 | ostringstream str; | ||
238 | + size_t indx; | ||
239 | |||
240 | // output symbol's summary data for each profile class | ||
241 | bool got_samples = false; | ||
242 | @@ -750,27 +767,21 @@ output_symbol(ostream & out, | ||
243 | |||
244 | string const image = get_image_name(symb->image_name, true); | ||
245 | string const qname = image + ":" + name; | ||
246 | - map<string, size_t>::iterator sd_it = symbol_data_table.find(qname); | ||
247 | - size_t si = xml_support->get_symbol_index(it); | ||
248 | |||
249 | - // if this is the first time we've seen this symbol, save it's index | ||
250 | - if (sd_it == symbol_data_table.end()) | ||
251 | - symbol_data_table[qname] = si; | ||
252 | - else | ||
253 | - si = sd_it->second; | ||
254 | + indx = xml_get_symbol_index(qname); | ||
255 | |||
256 | - out << init_attr(ID_REF, si); | ||
257 | + out << init_attr(ID_REF, indx); | ||
258 | |||
259 | if (need_details) { | ||
260 | ostringstream details; | ||
261 | - symbol_details_t & sd = symbol_details[si]; | ||
262 | + symbol_details_t & sd = symbol_details[indx]; | ||
263 | size_t const detail_lo = sd.index; | ||
264 | |||
265 | string detail_str = output_symbol_details(symb, sd.index, lo, hi); | ||
266 | |||
267 | if (detail_str.size() > 0) { | ||
268 | if (sd.id < 0) | ||
269 | - sd.id = si; | ||
270 | + sd.id = indx; | ||
271 | details << detail_str; | ||
272 | } | ||
273 | |||
274 | @@ -826,5 +837,170 @@ output_attribute(ostream & out, field_da | ||
275 | } | ||
276 | } | ||
277 | |||
278 | +xml_cg_formatter:: | ||
279 | +xml_cg_formatter(callgraph_container const * cg, symbol_collection & s) | ||
280 | + : | ||
281 | + xml_formatter(NULL, s), | ||
282 | + callgraph(cg) | ||
283 | +{ | ||
284 | + counts.total = callgraph->samples_count(); | ||
285 | +} | ||
286 | + | ||
287 | +void xml_cg_formatter::output(ostream & out) | ||
288 | +{ | ||
289 | + xml_support->build_subclasses(out); | ||
290 | + | ||
291 | + xml_support->output_program_structure(out); | ||
292 | + output_symbol_data(out); | ||
293 | + | ||
294 | + out << close_element(PROFILE); | ||
295 | +} | ||
296 | + | ||
297 | +void xml_cg_formatter:: | ||
298 | +output_symbol_core(ostream & out, | ||
299 | + symbol_entry const * symb, size_t lo, size_t hi) | ||
300 | +{ | ||
301 | + cg_symbol const * cg_symb = dynamic_cast<const cg_symbol *>(symb); | ||
302 | + ostringstream str; | ||
303 | + | ||
304 | + // output symbol's summary data for each profile class | ||
305 | + bool got_samples = false; | ||
306 | + | ||
307 | + for (size_t p = lo; p <= hi; ++p) { | ||
308 | + got_samples |= xml_support->output_summary_data(str, | ||
309 | + symb->sample.counts, p); | ||
310 | + } | ||
311 | + | ||
312 | + if (!got_samples) | ||
313 | + return; | ||
314 | + | ||
315 | + cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(symb->name) << " -->" << endl; | ||
316 | + | ||
317 | + out << open_element(SYMBOL, true); | ||
318 | + | ||
319 | + string const name = symbol_names.name(symb->name); | ||
320 | + assert(name.size() > 0); | ||
321 | + | ||
322 | + string const image = get_image_name(symb->image_name, true); | ||
323 | + string const qname = image + ":" + name; | ||
324 | + | ||
325 | + string const selfname = symbol_names.demangle(symb->name) + " [self]"; | ||
326 | + | ||
327 | + out << init_attr(ID_REF, xml_get_symbol_index(qname)); | ||
328 | + | ||
329 | + out << close_element(NONE, true); | ||
330 | + | ||
331 | + out << open_element(CALLERS); | ||
332 | + if (cg_symb) { | ||
333 | + cg_symbol::children::const_iterator cit; | ||
334 | + cg_symbol::children::const_iterator cend = cg_symb->callers.end(); | ||
335 | + | ||
336 | + for (cit = cg_symb->callers.begin(); cit != cend; ++cit) { | ||
337 | + ostringstream str1; | ||
338 | + string binary = get_image_name((cit)->app_name, true); | ||
339 | + string module = get_image_name((cit)->image_name, true); | ||
340 | + | ||
341 | + | ||
342 | + got_samples = false; | ||
343 | + | ||
344 | + for (size_t p = lo; p <= hi; ++p) { | ||
345 | + got_samples |= xml_support->output_summary_data(str1, cit->sample.counts, p); | ||
346 | + } | ||
347 | + | ||
348 | + if (!got_samples) | ||
349 | + continue; | ||
350 | + | ||
351 | + out << open_element(MODULE, true); | ||
352 | + out << init_attr(NAME, module) << close_element(NONE, true); | ||
353 | + | ||
354 | + cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(cit->name) << " -->" << endl; | ||
355 | + | ||
356 | + out << open_element(SYMBOL, true); | ||
357 | + | ||
358 | + string const name1 = symbol_names.name(cit->name); | ||
359 | + assert(name1.size() > 0); | ||
360 | + | ||
361 | + string const qname1 = module + ":" + name1; | ||
362 | + | ||
363 | + out << init_attr(ID_REF, xml_get_symbol_index(qname1)); | ||
364 | + | ||
365 | + out << close_element(NONE, true); | ||
366 | + | ||
367 | + out << str1.str(); | ||
368 | + | ||
369 | + out << close_element(SYMBOL); | ||
370 | + | ||
371 | + out << close_element(MODULE); | ||
372 | + } | ||
373 | + } | ||
374 | + out << close_element(CALLERS); | ||
375 | + | ||
376 | + out << open_element(CALLEES); | ||
377 | + if (cg_symb) { | ||
378 | + cg_symbol::children::const_iterator cit; | ||
379 | + cg_symbol::children::const_iterator cend = cg_symb->callees.end(); | ||
380 | + | ||
381 | + for (cit = cg_symb->callees.begin(); cit != cend; ++cit) { | ||
382 | + size_t indx; | ||
383 | + ostringstream str1; | ||
384 | + string binary = get_image_name((cit)->app_name, true); | ||
385 | + string module = get_image_name((cit)->image_name, true); | ||
386 | + bool self = false; | ||
387 | + | ||
388 | + got_samples = false; | ||
389 | + | ||
390 | + for (size_t p = lo; p <= hi; ++p) { | ||
391 | + got_samples |= xml_support->output_summary_data(str1, cit->sample.counts, p); | ||
392 | + } | ||
393 | + | ||
394 | + if (!got_samples) | ||
395 | + continue; | ||
396 | + | ||
397 | + out << open_element(MODULE, true); | ||
398 | + out << init_attr(NAME, module) << close_element(NONE, true); | ||
399 | + | ||
400 | + cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(cit->name) << " -->" << endl; | ||
401 | + | ||
402 | + out << open_element(SYMBOL, true); | ||
403 | + | ||
404 | + string name1 = symbol_names.name(cit->name); | ||
405 | + assert(name1.size() > 0); | ||
406 | + string const qname1 = module + ":" + name1; | ||
407 | + | ||
408 | + /* Find any self references and handle */ | ||
409 | + if (name1 == selfname) { | ||
410 | + self = true; | ||
411 | + indx = xml_get_symbol_index(qname); | ||
412 | + } else | ||
413 | + indx = xml_get_symbol_index(qname1); | ||
414 | + | ||
415 | + out << init_attr(ID_REF, indx); | ||
416 | + | ||
417 | + if (self) | ||
418 | + out << init_attr(SELFREF, "true"); | ||
419 | + | ||
420 | + out << close_element(NONE, true); | ||
421 | + | ||
422 | + out << str1.str(); | ||
423 | + | ||
424 | + out << close_element(SYMBOL); | ||
425 | + | ||
426 | + out << close_element(MODULE); | ||
427 | + } | ||
428 | + } | ||
429 | + out << close_element(CALLEES); | ||
430 | + | ||
431 | + // output summary | ||
432 | + out << str.str(); | ||
433 | + out << close_element(SYMBOL); | ||
434 | +} | ||
435 | + | ||
436 | + | ||
437 | +void xml_cg_formatter:: | ||
438 | +output_symbol(ostream & out, | ||
439 | + symbol_entry const * symb, size_t lo, size_t hi) | ||
440 | +{ | ||
441 | + output_symbol_core(out, symb, lo, hi); | ||
442 | +} | ||
443 | |||
444 | } // namespace format_output | ||
445 | Index: oprofile/libpp/format_output.h | ||
446 | =================================================================== | ||
447 | --- oprofile.orig/libpp/format_output.h | ||
448 | +++ oprofile/libpp/format_output.h | ||
449 | @@ -201,7 +201,7 @@ public: | ||
450 | |||
451 | /** output callgraph information according to the previously format | ||
452 | * specifier set by call(s) to add_format() */ | ||
453 | - void output(std::ostream & out, cg_collection const & syms); | ||
454 | + void output(std::ostream & out, symbol_collection const & syms); | ||
455 | }; | ||
456 | |||
457 | /// class to output a columned format symbols plus diff values | ||
458 | @@ -227,7 +227,7 @@ private: | ||
459 | class xml_formatter : public formatter { | ||
460 | public: | ||
461 | /// build a ready to use formatter | ||
462 | - xml_formatter(profile_container const & profile, | ||
463 | + xml_formatter(profile_container const * profile, | ||
464 | symbol_collection & symbols); | ||
465 | |||
466 | // output body of XML output | ||
467 | @@ -235,9 +235,8 @@ public: | ||
468 | |||
469 | /** output one symbol symb to out according to the output format | ||
470 | * specifier previously set by call(s) to add_format() */ | ||
471 | - void output_symbol(std::ostream & out, | ||
472 | - symbol_collection::const_iterator const it, | ||
473 | - size_t lo, size_t hi); | ||
474 | + virtual void output_symbol(std::ostream & out, | ||
475 | + symbol_entry const * symb, size_t lo, size_t hi); | ||
476 | |||
477 | /// output details for the symbol | ||
478 | std::string output_symbol_details(symbol_entry const * symb, | ||
479 | @@ -246,9 +245,12 @@ public: | ||
480 | /// set the output_details boolean | ||
481 | void show_details(bool); | ||
482 | |||
483 | + // output SymbolData XML elements | ||
484 | + void output_symbol_data(std::ostream & out); | ||
485 | + | ||
486 | private: | ||
487 | /// container we work from | ||
488 | - profile_container const & profile; | ||
489 | + profile_container const * profile; | ||
490 | |||
491 | // ordered collection of symbols associated with this profile | ||
492 | symbol_collection & symbols; | ||
493 | @@ -256,9 +258,6 @@ private: | ||
494 | /// true if we need to show details for each symbols | ||
495 | bool need_details; | ||
496 | |||
497 | - // output SymbolData XML elements | ||
498 | - void output_symbol_data(std::ostream & out); | ||
499 | - | ||
500 | // count of DetailData items output so far | ||
501 | size_t detail_count; | ||
502 | |||
503 | @@ -270,6 +269,28 @@ private: | ||
504 | format_flags fl, tag_t tag); | ||
505 | }; | ||
506 | |||
507 | +// callgraph XML output version | ||
508 | +class xml_cg_formatter : public xml_formatter { | ||
509 | +public: | ||
510 | + /// build a ready to use formatter | ||
511 | + xml_cg_formatter(callgraph_container const * callgraph, | ||
512 | + symbol_collection & symbols); | ||
513 | + | ||
514 | + // output body of XML output | ||
515 | + void output(std::ostream & out); | ||
516 | + | ||
517 | + /** output one symbol symb to out according to the output format | ||
518 | + * specifier previously set by call(s) to add_format() */ | ||
519 | + virtual void output_symbol(std::ostream & out, | ||
520 | + symbol_entry const * symb, size_t lo, size_t hi); | ||
521 | + | ||
522 | +private: | ||
523 | + /// container we work from | ||
524 | + callgraph_container const * callgraph; | ||
525 | + | ||
526 | + void output_symbol_core(std::ostream & out, | ||
527 | + symbol_entry const * symb, size_t lo, size_t hi); | ||
528 | +}; | ||
529 | |||
530 | } // namespace format_output | ||
531 | |||
532 | Index: oprofile/libpp/symbol.h | ||
533 | =================================================================== | ||
534 | --- oprofile.orig/libpp/symbol.h | ||
535 | +++ oprofile/libpp/symbol.h | ||
536 | @@ -55,8 +55,11 @@ struct sample_entry { | ||
537 | |||
538 | |||
539 | /// associate a symbol with a file location, samples count and vma address | ||
540 | -struct symbol_entry { | ||
541 | +class symbol_entry { | ||
542 | +public: | ||
543 | symbol_entry() : size(0) {} | ||
544 | + virtual ~symbol_entry() {} | ||
545 | + | ||
546 | /// which image this symbol belongs to | ||
547 | image_name_id image_name; | ||
548 | /// owning application name: identical to image name if profiling | ||
549 | @@ -92,7 +95,8 @@ typedef std::vector<symbol_entry const * | ||
550 | * the sample counts replaced with the relevant arc counts, whilst | ||
551 | * the cg_symbol retains its self count. | ||
552 | */ | ||
553 | -struct cg_symbol : public symbol_entry { | ||
554 | +class cg_symbol : public symbol_entry { | ||
555 | +public: | ||
556 | cg_symbol(symbol_entry const & sym) : symbol_entry(sym) {} | ||
557 | |||
558 | typedef std::vector<symbol_entry> children; | ||
559 | @@ -108,9 +112,12 @@ struct cg_symbol : public symbol_entry { | ||
560 | count_array_t total_callee_count; | ||
561 | }; | ||
562 | |||
563 | +/// a collection of sorted callgraph symbols (the objects themselves) | ||
564 | +typedef std::vector<cg_symbol> cg_collection_objs; | ||
565 | + | ||
566 | |||
567 | -/// a collection of sorted callgraph symbols | ||
568 | -typedef std::vector<cg_symbol> cg_collection; | ||
569 | +/// a collection of sorted callgraph symbols (pointers too, compatible with symbol_collection) | ||
570 | +//typedef std::vector<cg_symbol const *> cg_collection; | ||
571 | |||
572 | |||
573 | /// for storing diff %ages | ||
574 | Index: oprofile/libpp/symbol_sort.cpp | ||
575 | =================================================================== | ||
576 | --- oprofile.orig/libpp/symbol_sort.cpp | ||
577 | +++ oprofile/libpp/symbol_sort.cpp | ||
578 | @@ -146,23 +146,6 @@ sort(symbol_collection & syms, bool reve | ||
579 | |||
580 | |||
581 | void sort_options:: | ||
582 | -sort(cg_collection & syms, bool reverse_sort, bool lf) const | ||
583 | -{ | ||
584 | - long_filenames = lf; | ||
585 | - | ||
586 | - vector<sort_order> sort_option(options); | ||
587 | - for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) { | ||
588 | - if (find(sort_option.begin(), sort_option.end(), cur) == | ||
589 | - sort_option.end()) | ||
590 | - sort_option.push_back(cur); | ||
591 | - } | ||
592 | - | ||
593 | - stable_sort(syms.begin(), syms.end(), | ||
594 | - symbol_compare(sort_option, reverse_sort)); | ||
595 | -} | ||
596 | - | ||
597 | - | ||
598 | -void sort_options:: | ||
599 | sort(diff_collection & syms, bool reverse_sort, bool lf) const | ||
600 | { | ||
601 | long_filenames = lf; | ||
602 | Index: oprofile/libpp/symbol_sort.h | ||
603 | =================================================================== | ||
604 | --- oprofile.orig/libpp/symbol_sort.h | ||
605 | +++ oprofile/libpp/symbol_sort.h | ||
606 | @@ -44,12 +44,6 @@ struct sort_options { | ||
607 | /** | ||
608 | * Sort the given container by the given criteria. | ||
609 | */ | ||
610 | - void sort(cg_collection & syms, bool reverse_sort, | ||
611 | - bool long_filenames) const; | ||
612 | - | ||
613 | - /** | ||
614 | - * Sort the given container by the given criteria. | ||
615 | - */ | ||
616 | void sort(diff_collection & syms, bool reverse_sort, | ||
617 | bool long_filenames) const; | ||
618 | |||
619 | Index: oprofile/libpp/xml_utils.cpp | ||
620 | =================================================================== | ||
621 | --- oprofile.orig/libpp/xml_utils.cpp | ||
622 | +++ oprofile/libpp/xml_utils.cpp | ||
623 | @@ -257,13 +257,6 @@ void xml_utils::output_xml_header(string | ||
624 | cout << close_element(SETUP) << endl; | ||
625 | } | ||
626 | |||
627 | -size_t xml_utils::get_symbol_index(sym_iterator const it) | ||
628 | -{ | ||
629 | - return it - symbols_begin; | ||
630 | -} | ||
631 | - | ||
632 | - | ||
633 | - | ||
634 | class subclass_info_t { | ||
635 | public: | ||
636 | string unitmask; | ||
637 | @@ -589,7 +582,7 @@ void module_info::output_summary(ostream | ||
638 | void module_info::output_symbols(ostream & out) | ||
639 | { | ||
640 | for (sym_iterator it = begin; it != end; ++it) | ||
641 | - xml_out->output_symbol(out, it, lo, hi); | ||
642 | + xml_out->output_symbol(out, *it, lo, hi); | ||
643 | } | ||
644 | |||
645 | |||
646 | Index: oprofile/libutil++/xml_output.cpp | ||
647 | =================================================================== | ||
648 | --- oprofile.orig/libutil++/xml_output.cpp | ||
649 | +++ oprofile/libutil++/xml_output.cpp | ||
650 | @@ -47,8 +47,11 @@ string const xml_tag_map[] = { | ||
651 | "binary", | ||
652 | "module", | ||
653 | "name", | ||
654 | + "callers", | ||
655 | + "callees", | ||
656 | "symbol", | ||
657 | "idref", | ||
658 | + "self", | ||
659 | "detaillo", | ||
660 | "detailhi", | ||
661 | "symboltable", | ||
662 | Index: oprofile/libutil++/xml_output.h | ||
663 | =================================================================== | ||
664 | --- oprofile.orig/libutil++/xml_output.h | ||
665 | +++ oprofile/libutil++/xml_output.h | ||
666 | @@ -28,7 +28,8 @@ typedef enum { | ||
667 | THREAD, THREAD_ID, | ||
668 | BINARY, | ||
669 | MODULE, NAME, | ||
670 | - SYMBOL, ID_REF, DETAIL_LO, DETAIL_HI, | ||
671 | + CALLERS, CALLEES, | ||
672 | + SYMBOL, ID_REF, SELFREF, DETAIL_LO, DETAIL_HI, | ||
673 | SYMBOL_TABLE, | ||
674 | SYMBOL_DATA, STARTING_ADDR, | ||
675 | SOURCE_FILE, SOURCE_LINE, CODE_LENGTH, | ||
676 | Index: oprofile/pp/opreport.cpp | ||
677 | =================================================================== | ||
678 | --- oprofile.orig/pp/opreport.cpp | ||
679 | +++ oprofile/pp/opreport.cpp | ||
680 | @@ -378,7 +378,7 @@ void output_symbols(profile_container co | ||
681 | format_output::opreport_formatter * text_out = 0; | ||
682 | |||
683 | if (options::xml) { | ||
684 | - xml_out = new format_output::xml_formatter(pc, symbols); | ||
685 | + xml_out = new format_output::xml_formatter(&pc, symbols); | ||
686 | xml_out->show_details(options::details); | ||
687 | out = xml_out; | ||
688 | // for XML always output long filenames | ||
689 | @@ -445,25 +445,45 @@ void output_cg_symbols(callgraph_contain | ||
690 | { | ||
691 | column_flags output_hints = cg.output_hint(); | ||
692 | |||
693 | - cg_collection symbols = cg.get_symbols(); | ||
694 | + symbol_collection symbols = cg.get_symbols(); | ||
695 | + | ||
696 | options::sort_by.sort(symbols, options::reverse_sort, | ||
697 | options::long_filenames); | ||
698 | |||
699 | - format_output::cg_formatter out(cg); | ||
700 | + format_output::formatter * out; | ||
701 | + format_output::xml_cg_formatter * xml_out = 0; | ||
702 | + format_output::cg_formatter * text_out = 0; | ||
703 | |||
704 | - out.set_nr_classes(nr_classes); | ||
705 | - out.show_long_filenames(options::long_filenames); | ||
706 | - out.show_header(options::show_header); | ||
707 | - out.vma_format_64bit(output_hints & cf_64bit_vma); | ||
708 | - out.show_global_percent(options::global_percent); | ||
709 | + if (options::xml) { | ||
710 | + xml_out = new format_output::xml_cg_formatter(&cg, symbols); | ||
711 | + out = xml_out; | ||
712 | + // for XML always output long filenames | ||
713 | + out->show_long_filenames(true); | ||
714 | + } else { | ||
715 | + text_out = new format_output::cg_formatter(cg); | ||
716 | + out = text_out; | ||
717 | + out->show_long_filenames(options::long_filenames); | ||
718 | + } | ||
719 | + | ||
720 | + out->set_nr_classes(nr_classes); | ||
721 | + out->show_header(options::show_header); | ||
722 | + out->vma_format_64bit(output_hints & cf_64bit_vma); | ||
723 | + out->show_global_percent(options::global_percent); | ||
724 | |||
725 | format_flags flags = get_format_flags(output_hints); | ||
726 | if (multiple_apps) | ||
727 | flags = format_flags(flags | ff_app_name); | ||
728 | |||
729 | - out.add_format(flags); | ||
730 | + out->add_format(flags); | ||
731 | + | ||
732 | + if (options::xml) { | ||
733 | + xml_support = new xml_utils(xml_out, symbols, nr_classes, | ||
734 | + &options::symbol_filter, options::archive_path); | ||
735 | + xml_out->output(cout); | ||
736 | + } else { | ||
737 | + text_out->output(cout, symbols); | ||
738 | + } | ||
739 | |||
740 | - out.output(cout, symbols); | ||
741 | } | ||
742 | |||
743 | |||
744 | Index: oprofile/pp/opreport_options.cpp | ||
745 | =================================================================== | ||
746 | --- oprofile.orig/pp/opreport_options.cpp | ||
747 | +++ oprofile/pp/opreport_options.cpp | ||
748 | @@ -177,11 +177,6 @@ void check_options(bool diff) | ||
749 | } | ||
750 | |||
751 | if (xml) { | ||
752 | - if (callgraph) { | ||
753 | - cerr << "--callgraph is incompatible with --xml" << endl; | ||
754 | - do_exit = true; | ||
755 | - } | ||
756 | - | ||
757 | if (accumulated) { | ||
758 | cerr << "--accumulated is incompatible with --xml" << endl; | ||
759 | do_exit = true; | ||
diff --git a/meta/packages/oprofile/oprofile_cvs.bb b/meta/packages/oprofile/oprofile_cvs.bb index 3b9eae9110..a085cc41de 100644 --- a/meta/packages/oprofile/oprofile_cvs.bb +++ b/meta/packages/oprofile/oprofile_cvs.bb | |||
@@ -1,5 +1,5 @@ | |||
1 | PV = "0.9.2+cvs${SRCDATE}" | 1 | PV = "0.9.2+cvs${SRCDATE}" |
2 | PR = "r1" | 2 | PR = "r2" |
3 | SECTION = "devel" | 3 | SECTION = "devel" |
4 | DESCRIPTION = "OProfile is a system-wide profiler for Linux systems, capable \ | 4 | DESCRIPTION = "OProfile is a system-wide profiler for Linux systems, capable \ |
5 | of profiling all running code at low overhead." | 5 | of profiling all running code at low overhead." |
@@ -11,6 +11,7 @@ SRC_URI = "cvs://anonymous@oprofile.cvs.sourceforge.net/cvsroot/oprofile;module= | |||
11 | file://oparchive-debug-dir.patch;patch=1 \ | 11 | file://oparchive-debug-dir.patch;patch=1 \ |
12 | file://oparchive-list-files.patch;patch=1 \ | 12 | file://oparchive-list-files.patch;patch=1 \ |
13 | file://opreport-xml-output-fixes.patch;patch=1 \ | 13 | file://opreport-xml-output-fixes.patch;patch=1 \ |
14 | file://xml_callgraph.patch;patch=1 \ | ||
14 | file://acinclude.m4" | 15 | file://acinclude.m4" |
15 | S = "${WORKDIR}/oprofile" | 16 | S = "${WORKDIR}/oprofile" |
16 | 17 | ||