From: hanseld <ha...@us...> - 2008-04-28 21:23:59
|
Update of /cvsroot/oprofile/oprofile/libpp In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv15532/libpp Modified Files: profile_container.cpp profile.h parse_filename.h profile.cpp parse_filename.cpp filename_spec.h profile_spec.cpp op_header.h callgraph_container.cpp filename_spec.cpp op_header.cpp arrange_profiles.cpp Log Message: JIT support (for profiling Java applications) added Index: profile_container.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/profile_container.cpp,v retrieving revision 1.34 retrieving revision 1.35 diff -u -p -d -r1.34 -r1.35 --- profile_container.cpp 11 Dec 2007 13:16:15 -0000 1.34 +++ profile_container.cpp 28 Apr 2008 21:23:22 -0000 1.35 @@ -86,7 +86,6 @@ void profile_container::add(profile_t co profile_t::iterator_pair p_it = profile.samples_range(start, end); - count_type count = accumulate(p_it.first, p_it.second, 0ull); // skip entries with no samples @@ -105,7 +104,7 @@ void profile_container::add(profile_t co if (debug_info) { string filename; if (abfd.get_linenr(i, start, filename, - symb_entry.sample.file_loc.linenr)) { + symb_entry.sample.file_loc.linenr)) { symb_entry.sample.file_loc.filename = debug_names.create(filename); } @@ -149,7 +148,7 @@ profile_container::add_samples(op_bfd co if (debug_info) { string filename; if (abfd.get_linenr(sym_index, it.vma(), filename, - sample.file_loc.linenr)) { + sample.file_loc.linenr)) { sample.file_loc.filename = debug_names.create(filename); } Index: profile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/profile.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -p -d -r1.19 -r1.20 --- profile.h 10 May 2007 23:54:35 -0000 1.19 +++ profile.h 28 Apr 2008 21:23:22 -0000 1.20 @@ -138,7 +138,7 @@ private: * * Phew. */ - u32 start_offset; + u64 start_offset; }; @@ -163,7 +163,7 @@ class profile_t::const_iterator typedef ordered_samples_t::const_iterator iterator_t; public: const_iterator() : start_offset(0) {} - const_iterator(iterator_t it_, u32 start_offset_) + const_iterator(iterator_t it_, u64 start_offset_) : it(it_), start_offset(start_offset_) {} count_type operator*() const { return it->second; } @@ -181,7 +181,7 @@ public: private: iterator_t it; - u32 start_offset; + u64 start_offset; }; #endif /* !PROFILE_H */ Index: parse_filename.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/parse_filename.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -p -d -r1.3 -r1.4 --- parse_filename.h 25 Jan 2004 01:53:55 -0000 1.3 +++ parse_filename.h 28 Apr 2008 21:23:22 -0000 1.4 @@ -13,6 +13,8 @@ #include <string> +class extra_images; + /** * a convenience class to store result of parse_filename() */ @@ -38,6 +40,7 @@ struct parsed_filename * above components are built */ std::string filename; + bool jit_dumpfile_exists; }; @@ -48,6 +51,7 @@ std::ostream & operator<<(std::ostream & /** * parse a sample filename * @param filename in: a sample filename + * @param extra_found_images binary image location * * filename is split into constituent parts, the lib_image is optional * and can be empty on successfull call. All other error are fatal. @@ -55,6 +59,7 @@ std::ostream & operator<<(std::ostream & * * all errors throw an std::invalid_argument exception */ -parsed_filename parse_filename(std::string const & filename); +parsed_filename parse_filename(std::string const & filename, + extra_images const & extra_found_images); #endif /* !PARSE_FILENAME_H */ Index: profile.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/profile.cpp,v retrieving revision 1.28 retrieving revision 1.29 diff -u -p -d -r1.28 -r1.29 --- profile.cpp 15 Feb 2008 18:28:18 -0000 1.28 +++ profile.cpp 28 Apr 2008 21:23:22 -0000 1.29 @@ -126,9 +126,18 @@ void profile_t::add_sample_file(string c void profile_t::set_offset(op_bfd const & abfd) { - opd_header const & header = get_header(); - if (header.anon_start || header.is_kernel) - start_offset = abfd.get_start_offset(header.anon_start); + // if no bfd file has been located for this samples file, we can't + // shift sample because abfd.get_symbol_range() return the whole + // address space and setting a non zero start_offset will overflow + // in get_symbol_range() caller. + if (abfd.valid()) { + opd_header const & header = get_header(); + if (header.anon_start) { + start_offset = header.anon_start; + } else if (header.is_kernel) { + start_offset = abfd.get_start_offset(0); + } + } cverb << (vdebug) << "start_offset is now " << start_offset << endl; } Index: parse_filename.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/parse_filename.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -u -p -d -r1.10 -r1.11 --- parse_filename.cpp 21 Jan 2008 21:35:17 -0000 1.10 +++ parse_filename.cpp 28 Apr 2008 21:23:22 -0000 1.11 @@ -12,10 +12,12 @@ #include <vector> #include <string> #include <iostream> +#include <sys/stat.h> #include "parse_filename.h" #include "file_manip.h" #include "string_manip.h" +#include "locate_images.h" using namespace std; @@ -108,8 +110,11 @@ string const parse_anon(string const & s * * where /name/ denote a unique path component */ -parsed_filename parse_filename(string const & filename) +parsed_filename parse_filename(string const & filename, + extra_images const & extra_found_images) { + struct stat st; + string::size_type pos = filename.find_last_of('/'); if (pos == string::npos) { throw invalid_argument("parse_filename() invalid filename: " + @@ -167,11 +172,28 @@ parsed_filename parse_filename(string co break; if (anon) { - result.lib_image = parse_anon(path[i], path[i - 1]); + pos = filename_spec.rfind('.'); + pos = filename_spec.rfind('.', pos-1); + if (pos == string::npos) { + throw invalid_argument("parse_filename() pid.addr.addr name expected: " + + filename_spec); + } + string jitdump = filename_spec.substr(0, pos) + ".jo"; + // if a jitdump file exists, we point to this file + if (!stat(jitdump.c_str(), &st)) { + // later code assumes an optional prefix path + // is stripped from the lib_image. + result.lib_image = + extra_found_images.strip_path_prefix(jitdump); + result.jit_dumpfile_exists = true; + } else { + result.lib_image = parse_anon(path[i], path[i - 1]); + } i++; break; + } else { + result.lib_image += "/" + path[i]; } - result.lib_image += "/" + path[i]; } if (i == path.size()) Index: filename_spec.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/filename_spec.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -p -d -r1.5 -r1.6 --- filename_spec.h 7 May 2004 15:18:14 -0000 1.5 +++ filename_spec.h 28 Apr 2008 21:23:22 -0000 1.6 @@ -17,6 +17,7 @@ #include "generic_spec.h" class profile_spec; +class extra_images; /** * A class to split and store components of a sample filename. @@ -30,20 +31,24 @@ class filename_spec public: /** * @param filename the samples filename + * @param extra extra binary image location * * build a filename_spec from a samples filename */ - filename_spec(std::string const & filename); + filename_spec(std::string const & filename, + extra_images const & extra); filename_spec(); /** * @param filename a sample filename + * @param extra extra binary image location * * setup filename spec according to the samples filename. PP:3.19 to * 3.25 */ - void set_sample_filename(std::string const & filename); + void set_sample_filename(std::string const & filename, + extra_images const & extra); /** * @param rhs right hand side of the match operator Index: profile_spec.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/profile_spec.cpp,v retrieving revision 1.34 retrieving revision 1.35 diff -u -p -d -r1.34 -r1.35 --- profile_spec.cpp 15 Nov 2007 15:45:01 -0000 1.34 +++ profile_spec.cpp 28 Apr 2008 21:23:22 -0000 1.35 @@ -21,6 +21,7 @@ #include "glob_filter.h" #include "locate_images.h" #include "op_exception.h" +#include "op_header.h" using namespace std; @@ -366,7 +367,11 @@ bool valid_candidate(string const & base if (!is_prefix(sub, "/{root}/") && !is_prefix(sub, "/{kern}/")) return false; - filename_spec file_spec(filename); + // strip out generated JIT object files for samples of anonymous regions + if (is_jit_sample(sub)) + return false; + + filename_spec file_spec(filename, spec.extra_found_images); if (spec.match(file_spec)) { if (exclude_dependent && file_spec.is_dependent()) return false; Index: op_header.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/op_header.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -p -d -r1.6 -r1.7 --- op_header.h 19 Oct 2003 02:03:45 -0000 1.6 +++ op_header.h 28 Apr 2008 21:23:22 -0000 1.7 @@ -28,6 +28,8 @@ void op_check_header(opd_header const & h1, opd_header const & h2, std::string const & filename); +bool is_jit_sample(std::string const & filename); + /** * check mtime of samples file header against file * all error are fatal Index: callgraph_container.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/callgraph_container.cpp,v retrieving revision 1.42 retrieving revision 1.43 diff -u -p -d -r1.42 -r1.43 --- callgraph_container.cpp 21 Jan 2008 21:35:17 -0000 1.42 +++ callgraph_container.cpp 28 Apr 2008 21:23:22 -0000 1.43 @@ -450,7 +450,8 @@ void callgraph_container::populate(list< for (it = cg_files.begin(); it != end; ++it) { cverb << vdebug << "samples file : " << *it << endl; - parsed_filename caller_file = parse_filename(*it); + parsed_filename caller_file = + parse_filename(*it, extra_found_images); string const app_name = caller_file.image; image_error error; @@ -469,7 +470,8 @@ void callgraph_container::populate(list< image_format_failure, false, extra_found_images); - parsed_filename callee_file = parse_filename(*it); + parsed_filename callee_file = + parse_filename(*it, extra_found_images); extra_found_images.find_image_path(callee_file.cg_image, error, false); @@ -514,17 +516,17 @@ add(profile_t const & profile, op_bfd co // We must handle start_offset, this offset can be different for the // caller and the callee: kernel sample traversing the syscall barrier. - u32 caller_offset = 0; - - if (header.is_kernel || header.anon_start) - caller_offset = caller_bfd.get_start_offset(header.anon_start); - - u32 callee_offset = 0; + u32 caller_offset; + if (header.is_kernel) + caller_offset = caller_bfd.get_start_offset(0); + else + caller_offset = header.anon_start; - if (header.cg_to_is_kernel || header.cg_to_anon_start) { - callee_offset = - callee_bfd.get_start_offset(header.cg_to_anon_start); - } + u32 callee_offset; + if (header.cg_to_is_kernel) + callee_offset = callee_bfd.get_start_offset(0); + else + callee_offset = header.cg_to_anon_start; image_name_id image_id = image_names.create(image_name); image_name_id callee_image_id = image_names.create(callee_bfd.get_filename()); Index: filename_spec.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/filename_spec.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -u -p -d -r1.7 -r1.8 --- filename_spec.cpp 7 Aug 2005 11:15:51 -0000 1.7 +++ filename_spec.cpp 28 Apr 2008 21:23:22 -0000 1.8 @@ -13,14 +13,16 @@ #include "filename_spec.h" #include "parse_filename.h" #include "generic_spec.h" +#include "locate_images.h" using namespace std; -filename_spec::filename_spec(string const & filename) +filename_spec::filename_spec(string const & filename, + extra_images const & extra) { - set_sample_filename(filename); + set_sample_filename(filename, extra); } @@ -54,9 +56,10 @@ bool filename_spec::match(filename_spec } -void filename_spec::set_sample_filename(string const & filename) +void filename_spec::set_sample_filename(string const & filename, + extra_images const & extra) { - parsed_filename parsed = parse_filename(filename); + parsed_filename parsed = parse_filename(filename, extra); image = parsed.image; lib_image = parsed.lib_image; Index: op_header.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/op_header.cpp,v retrieving revision 1.27 retrieving revision 1.28 diff -u -p -d -r1.27 -r1.28 --- op_header.cpp 15 Feb 2008 18:28:18 -0000 1.27 +++ op_header.cpp 28 Apr 2008 21:23:22 -0000 1.28 @@ -7,6 +7,7 @@ * * @author John Levon * @author Philippe Elie + * @Modifications Daniel Hansel */ #include <iostream> @@ -31,9 +32,12 @@ #include "string_manip.h" #include "format_output.h" #include "xml_utils.h" +#include "cverb.h" using namespace std; +extern verbose vbfd; + void op_check_header(opd_header const & h1, opd_header const & h2, string const & filename) { @@ -51,13 +55,9 @@ void op_check_header(opd_header const & << filename << "\n"; throw op_fatal_error(os.str()); } - - if (h1.anon_start != h2.anon_start) { - ostringstream os; - os << "header anon_start flags are different for " - << filename << "\n"; - throw op_fatal_error(os.str()); - } + + // Note that in the generated ELF file for anonymous code the vma + // of the symbol is exaclty the same vma as the code had during sampling. // Note that we don't check CPU speed since that can vary // freely on the same machine @@ -70,6 +70,19 @@ set<string> warned_files; } +bool is_jit_sample(string const & filename) +{ + // suffix for JIT sample files (see FIXME in check_mtime() below) + string suf = ".jo"; + + string::size_type pos; + pos = filename.rfind(suf); + // for JIT sample files do not output the warning to stderr. + if (pos != string::npos && pos == filename.size() - suf.size()) + return true; + else + return false; +} void check_mtime(string const & file, opd_header const & header) { @@ -85,9 +98,18 @@ void check_mtime(string const & file, op // Files we couldn't get mtime of have zero mtime if (!header.mtime) { - cerr << "warning: could not check that the binary file " - << file << " has not been modified since " - "the profile was taken. Results may be inaccurate.\n"; + // FIXME: header.mtime for JIT sample files is 0. The problem could be that + // in opd_mangling.c:opd_open_sample_file() the call of fill_header() + // think that the JIT sample file is not a binary file. + if (is_jit_sample(file)) { + cverb << vbfd << "warning: could not check that the binary file " + << file << " has not been modified since " + "the profile was taken. Results may be inaccurate.\n"; + } else { + cerr << "warning: could not check that the binary file " + << file << " has not been modified since " + "the profile was taken. Results may be inaccurate.\n"; + } } else { static bool warned_already = false; Index: arrange_profiles.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/libpp/arrange_profiles.cpp,v retrieving revision 1.44 retrieving revision 1.45 diff -u -p -d -r1.44 -r1.45 --- arrange_profiles.cpp 29 Oct 2007 15:44:29 -0000 1.44 +++ arrange_profiles.cpp 28 Apr 2008 21:23:22 -0000 1.45 @@ -546,14 +546,15 @@ add_to_profile_sample_files(profile_samp */ profile_sample_files & find_profile_sample_files(list<profile_sample_files> & files, - parsed_filename const & parsed) + parsed_filename const & parsed, + extra_images const & extra) { list<profile_sample_files>::iterator it; list<profile_sample_files>::iterator const end = files.end(); for (it = files.begin(); it != end; ++it) { if (!it->sample_filename.empty()) { parsed_filename psample_filename = - parse_filename(it->sample_filename); + parse_filename(it->sample_filename, extra); if (psample_filename.lib_image == parsed.lib_image && psample_filename.image == parsed.image && psample_filename.profile_spec_equal(parsed)) @@ -563,7 +564,8 @@ find_profile_sample_files(list<profile_s list<string>::const_iterator cit; list<string>::const_iterator const cend = it->cg_files.end(); for (cit = it->cg_files.begin(); cit != cend; ++cit) { - parsed_filename pcg_filename = parse_filename(*cit); + parsed_filename pcg_filename = + parse_filename(*cit, extra); if (pcg_filename.lib_image == parsed.lib_image && pcg_filename.image == parsed.image && pcg_filename.profile_spec_equal(parsed)) @@ -583,11 +585,12 @@ find_profile_sample_files(list<profile_s * on the normal list of profiles otherwise. */ void -add_to_profile_set(profile_set & set, parsed_filename const & parsed, bool merge_by_lib) +add_to_profile_set(profile_set & set, parsed_filename const & parsed, + bool merge_by_lib, extra_images const & extra) { if (parsed.image == parsed.lib_image && !merge_by_lib) { profile_sample_files & sample_files = - find_profile_sample_files(set.files, parsed); + find_profile_sample_files(set.files, parsed, extra); add_to_profile_sample_files(sample_files, parsed); return; } @@ -596,9 +599,11 @@ add_to_profile_set(profile_set & set, pa list<profile_dep_set>::iterator const end = set.deps.end(); for (; it != end; ++it) { - if (it->lib_image == parsed.lib_image && !merge_by_lib) { + if (it->lib_image == parsed.lib_image && !merge_by_lib && + parsed.jit_dumpfile_exists == false) { profile_sample_files & sample_files = - find_profile_sample_files(it->files, parsed); + find_profile_sample_files(it->files, parsed, + extra); add_to_profile_sample_files(sample_files, parsed); return; } @@ -607,7 +612,7 @@ add_to_profile_set(profile_set & set, pa profile_dep_set depset; depset.lib_image = parsed.lib_image; profile_sample_files & sample_files = - find_profile_sample_files(depset.files, parsed); + find_profile_sample_files(depset.files, parsed, extra); add_to_profile_sample_files(sample_files, parsed); set.deps.push_back(depset); } @@ -618,21 +623,22 @@ add_to_profile_set(profile_set & set, pa * will have ensured the profile "fits", so now it's just a matter of * finding which sample file list it needs to go on. */ -void add_profile(profile_class & pclass, parsed_filename const & parsed, bool merge_by_lib) +void add_profile(profile_class & pclass, parsed_filename const & parsed, + bool merge_by_lib, extra_images const & extra) { list<profile_set>::iterator it = pclass.profiles.begin(); list<profile_set>::iterator const end = pclass.profiles.end(); for (; it != end; ++it) { if (it->image == parsed.image) { - add_to_profile_set(*it, parsed, merge_by_lib); + add_to_profile_set(*it, parsed, merge_by_lib, extra); return; } } profile_set set; set.image = parsed.image; - add_to_profile_set(set, parsed, merge_by_lib); + add_to_profile_set(set, parsed, merge_by_lib, extra); pclass.profiles.push_back(set); } @@ -649,7 +655,7 @@ arrange_profiles(list<string> const & fi list<string>::const_iterator const end = files.end(); for (; it != end; ++it) { - parsed_filename parsed = parse_filename(*it); + parsed_filename parsed = parse_filename(*it, extra); if (parsed.lib_image.empty()) parsed.lib_image = parsed.image; @@ -663,7 +669,7 @@ arrange_profiles(list<string> const & fi profile_class & pclass = find_class(temp_classes, parsed, merge_by); - add_profile(pclass, parsed, merge_by.lib); + add_profile(pclass, parsed, merge_by.lib, extra); } profile_classes classes; |