/** * @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 */