/**
* @file callgraph_container.h
* Container associating symbols and caller/caller symbols
*
* @remark Copyright 2004 OProfile authors
* @remark Read the file COPYING
*
* @author Philippe Elie
* @author John Levon
*/
#ifndef CALLGRAPH_CONTAINER_H
#define CALLGRAPH_CONTAINER_H
#include <set>
#include <vector>
#include <string>
#include "symbol.h"
#include "symbol_functors.h"
#include "string_filter.h"
#include "locate_images.h"
class profile_container;
class inverted_profile;
class profile_t;
class image_set;
class op_bfd;
/**
* During building a callgraph_container we store all caller/callee
* relationship in this container.
*
* An "arc" is simply a description of a call from one function to
* another.
*/
class arc_recorder {
public:
~arc_recorder() {}
/**
* Add a symbol arc.
* @param caller The calling symbol
* @param callee The called symbol
* @param arc_count profile data for the arcs
*
* If the callee is NULL, only the caller is added to the main
* list. This is used to initially populate the recorder with
* the symbols.
*/
void add(symbol_entry const & caller, symbol_entry const * callee,
count_array_t const & arc_count);
/// return all the cg symbols
symbol_collection const & get_symbols() const;
/**
* After population, build the final output, and do
* thresholding.
*/
void process(count_array_t total, double threshold,
string_filter const & filter);
private:
/**
* Internal structure used during collation. We use a map to
* allow quick lookup of children (we'll do this several times
* if we have more than one profile class). Each child maps from
* the symbol to the relevant arc data.
*/
struct cg_data {
cg_data() {}
typedef std::map<symbol_entry, count_array_t, less_symbol> children;
/// callers of this symbol
children callers;
/// callees of this symbol
children callees;
};
/**
* Sort and threshold callers and callees.
*/
void process_children(cg_symbol & sym, double threshold);
typedef std::map<symbol_entry, cg_data, less_symbol> map_t;
/// all the symbols (used during processing)
map_t sym_map;
/// symbol objects pointed to by pointers in vector cg_syms
cg_collection_objs cg_syms_objs;
/// final output data
symbol_collection cg_syms;
};
/**
* Store all callgraph information for the given profiles
*/
class callgraph_container {
public:
/**
* Populate the container, must be called once only.
* @param iprofiles sample file list including callgraph files.
* @param extra extra image list to fixup binary name.
* @param debug_info true if we must record linenr information
* @param threshold ignore sample percent below this threshold
* @param merge_lib merge library samples
* @param sym_filter symbol filter
*
* Currently all errors core dump.
* FIXME: consider if this should be a ctor
*/
void populate(std::list<inverted_profile> const & iprofiles,
extra_images const & extra, bool debug_info,
double threshold, bool merge_lib,
string_filter const & sym_filter);
/// return hint on how data must be displayed.
column_flags output_hint() const;
/// return the total number of samples.
count_array_t samples_count() const;
// return all the cg symbols
symbol_collection const & get_symbols() const;
private:
/**
* Record caller/callee for one cg file
* @param profile one callgraph file stored in a profile_t
* @param caller_bfd the caller bfd
* @param bfd_caller_ok true if we succefully open the binary
* @param callee_bfd the callee bfd
* @param app_name the owning application
* @param pc the profile_container holding all non cg samples.
* @param debug_info record linenr debug information
* @param pclass profile class nr
*/
void add(profile_t const & profile, op_bfd const & caller_bfd,
bool bfd_caller_ok, op_bfd const & callee_bfd,
std::string const & app_name, profile_container const & pc,
bool debug_info, size_t pclass);
void populate(std::list<image_set> const & lset,
std::string const & app_image,
size_t pclass, profile_container const & pc,
bool debug_info, bool merge_lib);
void populate(std::list<std::string> const & cg_files,
std::string const & app_image,
size_t pclass, profile_container const & pc,
bool debug_info, bool merge_lib);
/// record all main symbols
void add_symbols(profile_container const & pc);
/// Cached value of samples count.
count_array_t total_count;
/// A structured representation of the callgraph.
arc_recorder recorder;
public: // FIXME
extra_images extra_found_images;
};
#endif /* !CALLGRAPH_CONTAINER_H */