From 9aa8ffcea9980d24cc9c9f13d9dd51e46e6283bf Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 9 Sep 2009 15:45:28 -0700 Subject: PR10594: Provide a cached dwarf_getscopes_die This avoids repeated DIE traversal by caching all parents on the first call, so future calls are just a simple walk up parent links. * dwflpp.cxx (dwflpp::getscopes_die): New cached function that mimics libdw's dwarf_getscopes_die using cached parent links. (dwflpp::cache_die_parents): New function to build the parent cache. (dwflpp::~dwflpp): Clean up the parent caches. (dwflpp::iterate_over_labels): Use the cached getscopes_die. (dwflpp::find_variable_and_frame_base): Ditto. * tapsets.cxx (dwarf_derived_probe::saveargs): Ditto. (uprobe_derived_probe::saveargs): Ditto. (dwarf_var_expanding_visitor::visit_target_symbol_context): Ditto. --- dwflpp.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'dwflpp.h') diff --git a/dwflpp.h b/dwflpp.h index 74a3ae00..e047fcba 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -65,6 +65,12 @@ typedef unordered_map mod_cu_function_cache_t; // inline function die -> instance die[] typedef unordered_map*> cu_inl_function_cache_t; +// die -> parent die +typedef unordered_map cu_die_parent_cache_t; + +// cu die -> (die -> parent die) +typedef unordered_map mod_cu_die_parent_cache_t; + typedef std::vector func_info_map_t; typedef std::vector inline_instance_map_t; @@ -201,6 +207,8 @@ struct dwflpp void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg), void * data); + std::vector getscopes_die(Dwarf_Die* die); + Dwarf_Die *declaration_resolve(const char *name); mod_cu_function_cache_t cu_function_cache; @@ -292,6 +300,9 @@ private: cu_inl_function_cache_t cu_inl_function_cache; void cache_inline_instances (Dwarf_Die* die); + mod_cu_die_parent_cache_t cu_die_parent_cache; + void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die); + /* The global alias cache is used to resolve any DIE found in a * module that is stubbed out with DW_AT_declaration with a defining * DIE found in a different module. The current assumption is that -- cgit From 729455a739d4755269f20b73d2db231db2a1fdd7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 10 Sep 2009 17:06:11 -0700 Subject: PR10594 cont'd: Use parent die cache for variable lookup Variable lookup is usually done through the scopes from dwarf_getscopes at a particular pc. This requires an expensive traversal to find the inner-most die containing the pc. For cases where that containing die is known, e.g. at a particular function entry, we can do much better with our die_parent_cache. This may also help get more accurate variable scopes in cases where multiple dies contain a pc and the innermost isn't what we're trying to probe. For example, an inlined call chain of foo->bar->baz may all have the same entry pc, but if the probe was on function("bar"), we would want the variables in bar's scope, not baz's. * dwflpp.h (struct dwflpp): Remove pc_cached_scopes, num_cached_scopes, and cached_scopes, as they are now remembered by the caller. * dwflpp.cxx (dwflpp::getscopes): New - the DIE version uses the parent cache, and the pc version just defers to dwarf_getscopes. (dwflpp::print_locals, literal_stmt_for_local): Take a scopes vector. (dwflpp::find_variable_and_frame_base): Take a scopes vector from the caller instead of computing it every time. (dwflpp::dwarf_getscopes_cached): Removed. * tapsets.cxx (dwarf_var_expanding_visitor::getscopes): New cached lookup function which gets the scopes from the DIE if possible. (dwarf_var_expanding_visitor::visit_target_symbol): Call getscopes. --- dwflpp.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'dwflpp.h') diff --git a/dwflpp.h b/dwflpp.h index e047fcba..d379b265 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -208,6 +208,8 @@ struct dwflpp void * data); std::vector getscopes_die(Dwarf_Die* die); + std::vector getscopes(Dwarf_Die* die); + std::vector getscopes(Dwarf_Addr pc); Dwarf_Die *declaration_resolve(const char *name); @@ -253,7 +255,7 @@ struct dwflpp bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc); - std::string literal_stmt_for_local (Dwarf_Die *scope_die, + std::string literal_stmt_for_local (std::vector& scopes, Dwarf_Addr pc, std::string const & local, const target_symbol *e, @@ -302,6 +304,7 @@ private: mod_cu_die_parent_cache_t cu_die_parent_cache; void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die); + cu_die_parent_cache_t *get_die_parents(); /* The global alias cache is used to resolve any DIE found in a * module that is stubbed out with DW_AT_declaration with a defining @@ -328,10 +331,10 @@ private: static void loc2c_emit_address (void *arg, struct obstack *pool, Dwarf_Addr address); - void print_locals(Dwarf_Die *die, std::ostream &o); + void print_locals(std::vector& scopes, std::ostream &o); void print_members(Dwarf_Die *vardie, std::ostream &o); - Dwarf_Attribute *find_variable_and_frame_base (Dwarf_Die *scope_die, + Dwarf_Attribute *find_variable_and_frame_base (std::vector& scopes, Dwarf_Addr pc, std::string const & local, const target_symbol *e, @@ -385,11 +388,6 @@ private: void build_blacklist(); std::string get_blacklist_section(Dwarf_Addr addr); - Dwarf_Addr pc_cached_scopes; - int num_cached_scopes; - Dwarf_Die *cached_scopes; - int dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes); - // Returns the call frame address operations for the given program counter. Dwarf_Op *get_cfa_ops (Dwarf_Addr pc); -- cgit